Эта проблема аналогична проверке доступности полупрозрачной навигации, но не совсем. У меня есть Nexus 4, сверкнутый с эквивалентом CyanogenMod 11 или Android 4.4, и любое приложение, работающее в ландшафтном режиме с FLAG_TRANSLUCENT_NAVIGATION, не обладает прозрачностью в пользовательском интерфейсе системы, как в портретном режиме.
Та же проблема может быть воспроизведена на Nexus 5, поскольку я не видел ни одного приложения Google, созданного для Android 4.4 в ландшафтном режиме, с полупрозрачными кнопками.
Это код, который я использую
int API_LEVEL = android.os.Build.VERSION.SDK_INT; if (API_LEVEL >= 19) { getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION ); }
И хотя поверхность окна становится больше (и непригодна), нет прозрачности.
Поэтому вопрос в том, должен ли я сделать что-нибудь дополнительное, чтобы заставить его работать в ландшафтном режиме? Или это ошибка Android?
Я не знаю, намерены ли они изменить поведение, но это кажется преднамеренным. С тех пор, как в Android Kitkat появилась FLAG_TRANSLUCENT_NAVIGATION, у устройств с «телефоном» всегда была непрозрачная черная панель навигации в правой части экрана в ландшафте. Даже во время этого сообщения в Android Lollipop появился новый флаг ( FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
), который имеет такое же поведение, независимо от того, что было передано setStatusBarColor() )
.
Вот приблизительный код, который вы можете использовать, чтобы узнать, когда стиль панели навигации находится вне вашего контроля.
class MyActivity extends Activity { // ... boolean isNavigationForcedBlack() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { return true; } final int windowFlags = getWindow().getAttributes().flags; int navControlFlags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { navControlFlags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; } if ((windowFlags & navControlFlags) == 0) { return true; } boolean deviceHasOpaqueSideLandscapeNav = getDeviceSmallestWidthDp() < 600; boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; return deviceHasOpaqueSideLandscapeNav && isLandscape; } DisplayMetrics dm = new DisplayMetrics(); float getDeviceSmallestWidthDp() { getWindowManager().getDefaultDisplay().getRealMetrics(dm); float widthDp = dm.widthPixels / dm.density; float heightDp = dm.heightPixels / dm.density; return Math.min(widthDp, heightDp); } }
Вы можете увидеть, доступен ли полупрозрачный эффект на текущем устройстве, используя следующий код:
int id = getResources().getIdentifier("config_enableTranslucentDecor", "bool", "android"); if (id != 0 && getResources().getBoolean(id)) { // Translucent available Window w = getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); }
С помощью этого кода вы можете проверить, может ли устройство использовать флаги FLAG_TRANSLUCENT_NAVIGATION
и FLAG_TRANSLUCENT_STATUS
. Затем вы должны сказать, что вы хотите, чтобы панель действий, панель уведомлений и панель мягких кнопок перекрывали ваш макет ( setContentView(R.layout.yourlayout);
перед setContentView(R.layout.yourlayout);
в onCreate()
):
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
Не забудьте добавить некоторые дополнения к вашему контенту, чтобы избежать его недостижимости, поскольку он будет «скрыт» от этих элементов. Для этого вы можете добавить в свой макет атрибут android:fitsSystemWindows="true"
в своем основном контейнере.