我在我的应用中使用沉浸式模式,当它在Android 4.4及更高版本上运行时。 (http://developer.android.com/training/system-ui/immersive.html)
我的活动确实以全屏显示,我使用setOnSystemUiVisibilityChangeListener
按下音量键。我也有类似的代码将对话框放入沉浸式模式。
但是,当显示对话框时,导航。酒吧跳到屏幕上,然后立即撤退。当对话框被解除时,情况会更糟 - 导航。酒吧跳跃并调整背后的活动。
以下是我的支持沉浸式模式的课程。它只是在每个Activity的onResume上调用,并且在构建每个对话框时也会调用一个单独的函数。
我是否错过任何旗帜或回调,或者这是一个已知的Android问题?
public class ImmersiveModeHelper {
public ImmersiveModeHelper(Activity activity)
{
mActivity = activity;
}
@SuppressLint("NewApi")
public void supportFullScreenImmersiveMode()
{
MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveMode: ");
// Support full-screen immersive mode on Android 4.4 and up
if (Build.VERSION.SDK_INT >= 19)
{
// Get the needed flags by reflection and use them
try
{
final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
.getInt(null);
final int hideNavigationFlag = View.class
.getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
null);
// Set the flags to the window decor view
mActivity.getWindow().getDecorView()
.setSystemUiVisibility(immersiveFlag | hideNavigationFlag | fullScreenFlag);
// Set a callback to be called when visibility changes
// (workaround
// for volume keys)
mActivity
.getWindow()
.getDecorView()
.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener()
{
@Override
public void onSystemUiVisibilityChange(int visibility)
{
MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveMode().new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: " +
"");
if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
{
Handler uiHandler = UiThreadUtils.getUiHandler();
uiHandler.removeCallbacks(mHideSystemUiCallback);
uiHandler.postDelayed(mHideSystemUiCallback,
HIDE_SYSTEM_UI_DELAY_MILLI);
}
}
});
} catch (Exception e)
{
e.printStackTrace();
MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
}
} else
{
MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
}
}
public static void supportFullScreenImmersiveModeForDialog(final Dialog dlg)
{
MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveModeForDialog: ");
// Support full-screen immersive mode on Android 4.4 and up
if (Build.VERSION.SDK_INT >= 19)
{
final Window dlgWindow = dlg.getWindow();
// Get the needed flags by reflection and use them
try
{
final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
.getInt(null);
final int hideNavigationFlag = View.class
.getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
null);
// Set the flags to the window decor view
int flags = dlgWindow.getDecorView().getSystemUiVisibility();
flags |= (immersiveFlag | hideNavigationFlag | fullScreenFlag);
dlgWindow.getDecorView().setSystemUiVisibility(flags);
// Set a callback to be called when visibility changes
// (workaround for volume keys)
dlgWindow.getDecorView().setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener()
{
@Override
public void onSystemUiVisibilityChange(int visibility)
{
MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveModeForDialog(...).new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: ");
if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
{
Runnable hideSystemUiCallback = new Runnable()
{
@Override
public void run()
{
supportFullScreenImmersiveModeForDialog(dlg);
}
};
Handler uiHandler = UiThreadUtils.getUiHandler();
uiHandler.removeCallbacks(hideSystemUiCallback);
uiHandler.postDelayed(hideSystemUiCallback,
HIDE_SYSTEM_UI_DELAY_MILLI);
}
}
});
} catch (Exception e)
{
e.printStackTrace();
MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
}
} else
{
MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
}
}
private Activity mActivity;
private Runnable mHideSystemUiCallback = new Runnable()
{
@Override
public void run()
{
supportFullScreenImmersiveMode();
}
};
private static final int HIDE_SYSTEM_UI_DELAY_MILLI = 0;
}
答案 0 :(得分:4)
来自Google API: 包含其他系统UI标志(例如SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION和SYSTEM_UI_FLAG_LAYOUT_STABLE)以保持内容在系统栏隐藏和显示时不会调整大小是一种很好的做法。
您还应确保同时隐藏操作栏和其他UI控件。此代码段演示了如何隐藏和显示状态和导航栏,而无需调整内容大小:
// This snippet hides the system bars.
private void hideSystemUI() {
// Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show.
mDecorView.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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
希望这有帮助。
答案 1 :(得分:0)
在Dialog或BottomSheetDialogFragment中,您必须实现对我有用的解决方案。
第1步:
在对话框或BottomSheetDialog中,使用onActivityCreated方法编写此代码,
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
步骤2: 另外,请覆盖以下方法:
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
现在看魔术:)
答案 2 :(得分:0)
对我有用的是将以下内容添加到父布局xml:
android:fitsSystemWindows="true"