android - 如何在 Android IceCreamSandwich 中进入和退出沉浸式模式(API 15)

标签 android

当将以下代码放入我的主要 Activity 的 onCreate 方法时,我的应用程序应该进入沉浸式模式。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_original_);
        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 // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

问题是代码仅适用于 API 19 及更高版本,我想支持 API 15 或 16(强烈推荐 15)及更高版本。当我的应用程序使用 API 15/16 或更高版本时,如何进入和退出类似沉浸式模式?

最佳答案

使用 API15 这是不可能的:如果您检查标志,它们仅在 API16 中引入。但是别把精力和时间花在几乎被废弃的API14-15上,几乎全部升级到16。

但是你可以尝试,在 setContent 之前:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);

相反,我无法在 API16 中保持沉浸式模式。一旦点击屏幕并且界面不交互,它总是会放回去,基本上它总是处于“向后倾斜”状态。根据这个我们需要拆分代码。

编辑 18/10/2015

将 2 个静态函数放在 Utility 类中,并从 Activity 中调用它们。

private final Handler mSystemUiHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
public boolean handleMessage(Message message) {
    Utils.hideSystemUI(getWindow());
    return true;
}

@Override
protected void onResume() {
    Log.d(TAG, "onResume called!");
    super.onResume();
    //Allow button disappear/appear when keyboard shows/hides
    handleSystemUi();
    mSystemUiHandler.sendEmptyMessageDelayed(0, DELAY_FULLSCREEN);
}

private void handleSystemUi() {
    // Create the change listener to listen for flag changes and reset IMMERSIVE_STICKY
    enter code hereView decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {
            if ( (visibility & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == 0
                    || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 ) {
                mSystemUiHandler.removeMessages(0);
                mSystemUiHandler.sendEmptyMessageDelayed(0, DELAY_FULLSCREEN);
            }
        }
    });
}

@TargetApi(Build.VERSION_CODES.KITKAT)
public static void hideSystemUI(final Window window) {
    if (hasKitkat()) {
        // KITKAT (4.4) mode: hide the soft nav bar (Immersive mode)
        View decorView = window.getDecorView();
        decorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // [API 14] hide nav bar!
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // [API 16] // hide nav bar, always pretend the nav bar is missing
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE // [API 16] fix screen resolution for app to minimum UI state
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // [API 16] always pretend we're fullscreen, even when not fullscreen
                | View.SYSTEM_UI_FLAG_FULLSCREEN // [API 16] hide status bar, fullscreen mode
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // [API 19] hide everything, and fade it if/when it comes back
        );

    } else if (hasHoneycomb()) {
        // HONEYCOMB to JELLYBEAN (3.0 - 4.3) mode: hide status bar, allow nav bar
        View decorView = window.getDecorView();
        decorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE // [API 16] fix screen resolution for app to minimum UI state
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // [API 16] always pretend we're fullscreen, even when not fullscreen
                | View.SYSTEM_UI_FLAG_FULLSCREEN // [API 16] hide status bar, fullscreen mode
                | View.SYSTEM_UI_FLAG_LOW_PROFILE // [API 14] dim on-screen UI
        );
    }
}

//In case you need to show manually
public static void showSystemUI(Window window) {
    window.getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

不幸的是,这还不够:有些设备也需要这些:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    Log.d(TAG, "onWindowFocusChanged hasFocus="+hasFocus);
    if (hasFocus) {
        mSystemUiHandler.removeMessages(0);
        mSystemUiHandler.sendEmptyMessageDelayed(0, DELAY_FULLSCREEN);
    }
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK
            || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
            || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
        mSystemUiHandler.sendEmptyMessageDelayed(0, DELAY_FULLSCREEN);
    }
    return super.onKeyDown(keyCode, event);
}

关于android - 如何在 Android IceCreamSandwich 中进入和退出沉浸式模式(API 15),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32238182/

相关文章:

android - 我在 Android 对话的彩信地址字段中的电话号码

java - Android Junit 测试位图资源

java - 在Android中通过扬声器强制输出声音

java - 在 Firebase 中查询组的正确做法

android - 如何检测 Xperia Play 中打开的 slider

android - 已跳过 setExact 方法调用。警报未按预期触发

java - Gradle : package com. 解析不存在

Android Studio 在调试器中找不到局部变量

android - 在 Android 中以管理员身份禁用应用程序之前需要密码

android - 我想在我的按钮上使用 Widget.Button.Transparent 样式