У меня возникли проблемы с возвратом из режима погружения в ActionBarActivity
. Я создал простое приложение, чтобы проиллюстрировать эту проблему. Существует макет с одной кнопкой для переключения режима погружения. При «возвращении» из режима погружения панель действий смещается вниз от своего исходного положения, примерно на то же расстояние, на которое она обычно смещается от верхней части экрана.
Я пробовал это на Nexus 4 с Lollipop. Такого поведения не было до Lollipop.
Скриншоты до, погружено, после.
Простой ActionBarActivity
, который иллюстрирует эту проблему:
public class MainActivity extends ActionBarActivity {
private boolean immersed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void enterImmersiveMode() {
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
immersed = true;
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void leaveImmersiveMode() {
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
immersed = false;
// recreate();
}
}
public void toggleImmersive(View v) {
if (immersed) {
leaveImmersiveMode();
} else {
enterImmersiveMode();
}
}
}
Ничего особенного в манифесте:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.immersivetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="ImmersiveTest"
android:theme="@style/Theme.AppCompat" >
<activity
android:name=".MainActivity"
android:label="ImmersiveTest" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Тривиальный макет:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.immersivetest.MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="toggle immersive"
android:onClick="toggleImmersive"
/>
</RelativeLayout>
Обходной путь, который я использую на данный момент, — это вызвать recreate()
после выхода из режима погружения, но он выглядит немного «глючным».
Если я поднимаю minSdkVersion
и использую Activity
вместо ActionBarActivity
, т.е. не использую библиотеку поддержки, то такого поведения не наблюдается.
Я понимаю, что иммерсивный режим доступен только в KitKat+ и мне не нужно использовать ActionBarActivity
из библиотеки поддержки, но готовый продукт должен будет работать на API версии 8+, а иммерсивный режим является необязательным дополнением.
Некоторые другие обходные пути, о которых я подумал и отклонил на данный момент:
- Иметь средство запуска оболочки
Activity
, которое немедленно программно перенаправляется наActionBarActivity
для более ранних версий API. - Наличие нескольких приложений по версии API.
Любой из этих вариантов звучит как много дополнительного обслуживания.
Есть ли что-нибудь еще, что я мог бы попробовать? Есть ли в приведенном выше коде явные ошибки в отношении возврата из режима погружения?
Обновить
С тех пор я обновил Nexus 4 до версии 5.1 и библиотеку поддержки до версии 22.1.1, и поведение осталось прежним. Я также обновил код, чтобы использовать новый AppCompatActivity
, так как ActionBarActivity
теперь устарел. Поведение, опять же, то же самое.
public class MainActivity extends AppCompatActivity {
// no changes here
}
Обновить
Это странное поведение также распространяется на ландшафтный режим. В дополнение к смещению в верхней части экрана также имеется смещение вправо от экрана между концом панели действий и кнопками навигации. Интересно, что это смещение снова похоже на размер «полосы» навигационной кнопки, то есть больше, чем смещение вверху.
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
. Похоже, без этой проблемы невозможно восстановить исходные флаги. Глядя на скриншот после, опубликованный выше (imgur.com/aaQu11i), кажется, что верхнее пространство равно в статусбар, а правое пространство равно высоте раскладки софт-кнопок. Это как раз и мой случай. Использование minSdk=19, targetSdk=28, протестировано на Android 8.1.0. - person Georgios   schedule 05.04.2019