玩轉(zhuǎn)Android上透明狀態(tài)欄,全屏顯示以及沉浸模式(Immersive Mode)

在Android上為了實(shí)現(xiàn)全屏顯示,透明狀態(tài)欄,沉浸模式等效果,往往需要我們掌握和系統(tǒng)UI顯示隱藏相關(guān)的各種Flag。Android上API版本混亂,各種Flag林立。今天我們就來聊聊這些Flags。

在Android Kitkat中引入Immersive Mode


imm-states.png

相關(guān)API

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

相關(guān)Flag

WindowManager.LayoutParams.FLAG_FULLSCREEN
隱藏狀態(tài)欄

View.SYSTEM_UI_FLAG_VISIBLE API 14
默認(rèn)標(biāo)記

View.SYSTEM_UI_FLAG_LOW_PROFILE API 14
低調(diào)模式, 會(huì)隱藏不重要的狀態(tài)欄圖標(biāo)

View.SYSTEM_UI_FLAG_LAYOUT_STABLE API 16
保持整個(gè)View穩(wěn)定, 常和控制System UI懸浮, 隱藏的Flags共用, 使View不會(huì)因?yàn)镾ystem UI的變化而重新layout

View.SYSTEM_UI_FLAG_FULLSCREEN API 16
狀態(tài)欄隱藏,效果同設(shè)置WindowManager.LayoutParams.FLAG_FULLSCREEN

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN API 16
視圖延伸至狀態(tài)欄區(qū)域,狀態(tài)欄上浮于視圖之上

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION API 14
隱藏導(dǎo)航欄

View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION API 16
視圖延伸至導(dǎo)航欄區(qū)域,導(dǎo)航欄上浮于視圖之上

View.SYSTEM_UI_FLAG_IMMERSIVE API 19
沉浸模式, 隱藏狀態(tài)欄和導(dǎo)航欄, 并且在第一次會(huì)彈泡提醒, 并且在狀態(tài)欄區(qū)域滑動(dòng)可以呼出狀態(tài)欄(這樣會(huì)系統(tǒng)會(huì)清楚之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標(biāo)志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一個(gè)或兩個(gè)同時(shí)設(shè)置。

View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY API 19
與上面唯一的區(qū)別是, 呼出隱藏的狀態(tài)欄后不會(huì)清除之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標(biāo)志,在一段時(shí)間后將再次隱藏系統(tǒng)欄)

參考Reference

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

組合搭配上面的Flag,我們可以實(shí)現(xiàn)沉浸模式,透明狀態(tài)欄等各種你想要的樣子。

使用場(chǎng)景

透明狀態(tài)欄

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); //也可以設(shè)置成灰色透明的,比較符合Material Design的風(fēng)格
}

全屏顯示

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);
        }
    }

沉浸模式(通過點(diǎn)擊內(nèi)容區(qū)域控制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);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容