在Android上为了实现全屏显示,透明状态栏,沉浸模式等效果,往往需要我们掌握和系统UI显示隐藏相关的各种Flag。Android上API版本混乱,各种Flag林立。今天我们就来聊聊这些Flags。

在Android Kitkat中引入Immersive Mode


imm-states.png

相关API

Window#setFlags
View#setSystemUiVisibility (Android 3.0开始提供)

相关Flag

WindowManager.LayoutParams.FLAG_FULLSCREEN
隐藏状态栏

View.SYSTEM_UI_FLAG_VISIBLE API 14
默认标记

View.SYSTEM_UI_FLAG_LOW_PROFILE API 14
低调模式, 会隐藏不重要的状态栏图标

View.SYSTEM_UI_FLAG_LAYOUT_STABLE API 16
保持整个View稳定, 常和控制System UI悬浮, 隐藏的Flags共用, 使View不会因为System UI的变化而重新layout

View.SYSTEM_UI_FLAG_FULLSCREEN API 16
状态栏隐藏,效果同设置WindowManager.LayoutParams.FLAG_FULLSCREEN

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN API 16
视图延伸至状态栏区域,状态栏上浮于视图之上

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION API 14
隐藏导航栏

View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION API 16
视图延伸至导航栏区域,导航栏上浮于视图之上

View.SYSTEM_UI_FLAG_IMMERSIVE API 19
沉浸模式, 隐藏状态栏和导航栏, 并且在第一次会弹泡提醒, 并且在状态栏区域滑动可以呼出状态栏(这样会系统会清楚之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一个或两个同时设置。

View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY API 19
与上面唯一的区别是, 呼出隐藏的状态栏后不会清除之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志,在一段时间后将再次隐藏系统栏)

参考Reference

https://developer.android.com/training/system-ui/immersive.html#sticky
https://www.youtube.com/embed/cBi8fjv90E4

组合搭配上面的Flag,我们可以实现沉浸模式,透明状态栏等各种你想要的样子。

使用场景

透明状态栏

style_color_colorscheme_palette1_example.png
if (Build.VERSION.SDK_INT >= 21) {    View decorView = getWindow().getDecorView();    int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;    decorView.setSystemUiVisibility(option);    getWindow().setStatusBarColor(Color.TRANSPARENT); //也可以设置成灰色透明的,比较符合Material Design的风格}

全屏显示

View decorView = getWindow().getDecorView();int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION        | View.SYSTEM_UI_FLAG_FULLSCREEN;decorView.setSystemUiVisibility(option);

沉浸模式(普通Immersive Mode)

imm-states.png
 @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if (hasFocus && Build.VERSION.SDK_INT >= 19) {            View decorView = getWindow().getDecorView();            decorView.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);        }    }

沉浸模式(通过点击内容区域控制System UI的显示和隐藏)

import android.os.Handler;import android.os.Message;import android.support.v7.app.ActionBar;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.GestureDetector;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;public class MainActivity extends AppCompatActivity {    private static final int INITIAL_DELAY = 1500;    private View mDecorView;    private ActionBar mActionBar;    private View mContentView;    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            hideSystemUI();        }    };    private GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener(){        @Override        public boolean onSingleTapUp(MotionEvent e) {            if ((mDecorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0){                hideSystemUI();            }else {                showSystemUI();            }            return true;        }    });    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mDecorView = getWindow().getDecorView();        mContentView = LayoutInflater.from(this).inflate(R.layout.activity_immersive, null);        setContentView(mContentView);        mDecorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {            @Override            public void onSystemUiVisibilityChange(int visibility) {                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0){                    //systemUI is visible                    mActionBar.show();                }else {                    //systemUI is invisible                    mActionBar.hide();                }            }        });        mContentView.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                gestureDetector.onTouchEvent(event);                return true;            }        });        mActionBar = getSupportActionBar();        mActionBar.setShowHideAnimationEnabled(true);        showSystemUI();    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if (hasFocus){            delayedHide(INITIAL_DELAY);        }else {            handler.removeMessages(0);            showSystemUI();        }    }    private void delayedHide(int delay){        handler.removeMessages(0);        handler.sendEmptyMessageDelayed(0, delay);    }    private void hideSystemUI(){        mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                        |View.SYSTEM_UI_FLAG_HIDE_NAVIGATION                                        |View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION                                        |View.SYSTEM_UI_FLAG_FULLSCREEN                                        |View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                        |View.SYSTEM_UI_FLAG_IMMERSIVE);    }    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. Android(安卓)源码的建造者模式
  2. Android(安卓)M新特性Doze and App Standby模式详解
  3. Android(安卓)- 隐藏最顶端的通知条(Top Notification Bar)
  4. Android(安卓)基础-Activity的使用(二)
  5. S5PV210 三个Camera Interface/CAMIF/FIMC的区别
  6. Android恢复出厂设置流程分析
  7. ViewModels 和 LiveData:模式 +反模式
  8. Android(安卓)MVPR 架构模式-Part1
  9. android状态栏颜色与沉浸式适配

随机推荐

  1. Android之提示Unable to instantiate fra
  2. android paint设置字体 中文字体 楷体 和
  3. android Notification 通知封装
  4. Unity android 读取文件,读取APK包文件
  5. Android第4坑:Android项目中使用lambda表
  6. Android Studio更新到3.1以后老项目跑不
  7. android handle looper 使用误区
  8. 【Android】JSON应用
  9. android客户定制SDK常见修改
  10. Android 录屏功能的实现