MaterialDesign--(8)沉浸式設計

什么是沉浸式凹髓?

沉浸式這個概念提出來很久了孵坚,相信大家也都知道是什么付枫。是什么我不啰嗦了,反正玩來玩去就是在玩狀態(tài)欄的顏色狗热。

我記得 MaterialDesign 系列的第一篇文章就給大家分享了一張圖钞馁。

對,沒錯匿刮,我們今天要講的就是圖上的StatusBarColor僧凰。沉浸式也就是在玩這個 StatuBarColor,其實沒什么意思熟丸。
如 全民TV 的首頁設計

WechatIMG10.png

怎么用

getWindow().setStatusBarColor(int color);
好了训措,講完了。

兼容性問題

剛剛這個方法僅適用與5.0+的手機虑啤,如果要兼容5.0以下的手機隙弛,則狀態(tài)欄只支持透明效果,但是沒有 api 提供去設置顏色狞山。
4.4以前的手機不支持修改狀態(tài)欄顏色
現(xiàn)在我們就來看看怎么修改4.4~5.0的狀態(tài)欄顏色全闷。
首先我們的,系統(tǒng)中有一個 windowTranslucentStatus 屬性萍启,不知道大家用過沒总珠,就是設置狀態(tài)欄為半透明屏鳍,并且會被 View 填充。然后我們的思路就是局服,抽取出 TranslucentActivity钓瞭,然后提供方法,讓 Toolbar 填充狀態(tài)欄淫奔。
第一步山涡,在 values-v19/style.xml 文件里面給 style 添加下面這條屬性

<item name="android:windowTranslucentStatus">true</item>

第二步,使用繼承了這個 Theme 的 的主題給 Activity唆迁。
第三步鸭丛,抽取 BaseTranslucentActivity

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public class BaseTranslucentActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //判斷版本,如果[4.4,5.0)就設置狀態(tài)欄和導航欄為透明
    if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT
            &&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP){
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //設置虛擬導航欄為透明
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    }
}

@SuppressLint("NewApi")
public void setOrChangeTranslucentColor(Toolbar toolbar,int translucentPrimaryColor){
    //判斷版本,如果[4.4,5.0)就設置狀態(tài)欄和導航欄為透明
    if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT
            &&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP){
        if(toolbar!=null){
            //1.先設置toolbar的高度
            LayoutParams params = toolbar.getLayoutParams();
            int statusBarHeight = getStatusBarHeight(this);
            params.height += statusBarHeight ;
            toolbar.setLayoutParams(params );
            //2.設置paddingTop,以達到狀態(tài)欄不遮擋toolbar的內(nèi)容唐责。
            toolbar.setPadding(
                    toolbar.getPaddingLeft(),
                    toolbar.getPaddingTop()+getStatusBarHeight(this),
                    toolbar.getPaddingRight(),
                    toolbar.getPaddingBottom());
            //設置頂部的顏色
            toolbar.setBackgroundColor(translucentPrimaryColor);
        }else if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.LOLLIPOP){
        getWindow().setNavigationBarColor(translucentPrimaryColor);
        getWindow().setStatusBarColor(translucentPrimaryColor);
    }else{
        //<4.4的鳞溉,不做處理
    }
}


private int getNavigationBarHeight(Context context) {
    return getSystemComponentDimen(this, "navigation_bar_height");
}

/**
 * 獲取狀態(tài)欄的高度
 * @param context
 * @return
 */
private int getStatusBarHeight(Context context) {
    // 反射手機運行的類:android.R.dimen.status_bar_height.
    return getSystemComponentDimen(this, "status_bar_height");
}

private static int getSystemComponentDimen(Context context, String dimenName){
    // 反射手機運行的類:android.R.dimen.status_bar_height.
    int statusHeight = -1;
    try {
        Class<?> clazz = Class.forName("com.android.internal.R$dimen");
        Object object = clazz.newInstance();
        String heightStr = clazz.getField(dimenName).get(object).toString();
        int height = Integer.parseInt(heightStr);
        //dp--->px
        statusHeight = context.getResources().getDimensionPixelSize(height);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return statusHeight;
}

private static boolean hasNavigationBarShow(WindowManager wm){
    Display display = wm.getDefaultDisplay();
    DisplayMetrics outMetrics = new DisplayMetrics();
    //獲取整個屏幕的高度
    display.getRealMetrics(outMetrics);
    int heightPixels = outMetrics.heightPixels;
    int widthPixels = outMetrics.widthPixels;
    //獲取內(nèi)容展示部分的高度
    outMetrics = new DisplayMetrics();
    display.getMetrics(outMetrics);
    int heightPixels2 = outMetrics.heightPixels;
    int widthPixels2 = outMetrics.widthPixels;
    int w = widthPixels-widthPixels2;
    int h = heightPixels-heightPixels2;
    return  w>0||h>0;//豎屏和橫屏兩種情況。
}
}

代碼里面的注釋清晰明了鼠哥,簡單粗暴熟菲。寶寶在做這一塊兼容性開發(fā)的時候踩過很多很多的坑,查了很多資料朴恳,最后才有了這個類抄罕。使用反射機制獲取代碼中狀態(tài)欄的高度,然后再給 Toolbar 設置 PaddingTop菜皂,然后就 Ok 了贞绵。
當然厉萝,你也可以用 fitsSystemWindows 為true 來恍飘,實現(xiàn),那不那個需要給每個activity 的 xml 都設置這個屬性谴垫,多麻煩章母,哈哈哈~

第二個問題:可能很多同學都會有這樣的場景需求,我們需要一個全透明的狀態(tài)欄覆蓋在圖片上方翩剪,如下圖

WechatIMG8.jpeg

但是實際上卻變成了這樣乳怎,半透明

WechatIMG9.png

媽賣批,這是為什么前弯,我明明設置了 windowTranslucentStatus 為 true蚪缀,系統(tǒng)控件可以填充狀態(tài)欄,然后再把狀態(tài)欄設置為透明色啊恕出。
后來询枚,終于在一篇博客中找到了解決方案~~

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

不用設置 windowTranslucentStatus 為 true,直接使用這兩個 flag 就好了浙巫,不會的同學趕緊做筆記~~

問題解決了金蜀,那么這些 flag 到底有什么作用呢刷后,我們直接點擊這個 flag 就可以看源碼,源碼里面都有英語注釋的渊抄,下面是我統(tǒng)計好的一些 flag 的作用尝胆。

參數(shù) api 版本 含義
View.SYSTEM_UI_FLAG_VISIBLE 14 默認標記
View.SYSTEM_UI_FLAG_LOW_PROFILE 14 低功耗模式, 會隱藏狀態(tài)欄圖標, 在4.0上可以實現(xiàn)全屏
View.SYSTEM_UI_FLAG_LAYOUT_STABLE 16 保持整個View穩(wěn)定, 常跟bar 懸浮, 隱藏共用, 使View不會因為SystemUI的變化而做layout
View.SYSTEM_UI_FLAG_FULLSCREEN 16 狀態(tài)欄隱藏
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 16 狀態(tài)欄上浮于Activity
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 14 隱藏導航欄
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 16 導航欄上浮于Activity
View.SYSTEM_UI_FLAG_IMMERSIVE 19 Kitkat新加入的Flag, 沉浸模式, 可以隱藏掉status跟navigation bar, 并且在第一次會彈泡提醒, 它會覆蓋掉之前兩個隱藏bar的標記, 并且在bar出現(xiàn)的位置滑動可以呼出bar
View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY 19 與上面唯一的區(qū)別是, 呼出隱藏的bar后會自動再隱藏掉

然后這里設置的 flag 會和WindowManger 的一些 flag相互影響,如果使用的過程中护桦,出現(xiàn)了預測之外的效果含衔,可以去看看源碼注釋,上面有說明哪些 flag 會影響到哪些 flag二庵,或許能解決問題抱慌。

沉浸式牽涉到的知識點也就這些,有什么問題留言吧~

上周五有了新需求眨猎,所以這篇文章晚來了今天抑进,Sorry~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市睡陪,隨后出現(xiàn)的幾起案子寺渗,更是在濱河造成了極大的恐慌,老刑警劉巖兰迫,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件信殊,死亡現(xiàn)場離奇詭異,居然都是意外死亡汁果,警方通過查閱死者的電腦和手機涡拘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來据德,“玉大人鳄乏,你說我怎么就攤上這事〖” “怎么了橱野?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長善玫。 經(jīng)常有香客問我水援,道長,這世上最難降的妖魔是什么茅郎? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任蜗元,我火速辦了婚禮,結(jié)果婚禮上系冗,老公的妹妹穿的比我還像新娘奕扣。我一直安慰自己,他們只是感情好毕谴,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布成畦。 她就那樣靜靜地躺著距芬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪循帐。 梳的紋絲不亂的頭發(fā)上框仔,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音拄养,去河邊找鬼离斩。 笑死,一個胖子當著我的面吹牛瘪匿,可吹牛的內(nèi)容都是我干的跛梗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼棋弥,長吁一口氣:“原來是場噩夢啊……” “哼核偿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顽染,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤漾岳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粉寞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尼荆,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年唧垦,在試婚紗的時候發(fā)現(xiàn)自己被綠了捅儒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡振亮,死狀恐怖巧还,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情双炕,我是刑警寧澤狞悲,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站妇斤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丹拯。R本人自食惡果不足惜站超,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乖酬。 院中可真熱鬧死相,春花似錦、人聲如沸咬像。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肮柜,卻和暖如春陷舅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背审洞。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工莱睁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芒澜。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓仰剿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親痴晦。 傳聞我的和親對象是個殘疾皇子南吮,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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

  • 前言 首先請大家看幾張圖: 以上的效果,一般我們統(tǒng)稱為沉浸式狀態(tài)欄誊酌。其實旨袒,這種叫法不是很準確,而且也沒有沉浸式狀態(tài)...
    宇是我閱讀 3,799評論 2 28
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評論 25 707
  • 一术辐、前言 其實我是不打算寫這篇文章的砚尽,為什么呢?因為關于沉浸式狀態(tài)欄的文章太多了辉词,隨便google一下就能出來幾十...
    依然范特稀西閱讀 44,218評論 27 180
  • 何謂沉浸式狀態(tài)欄## 說白了必孤,沉浸式狀態(tài)欄本質(zhì)上就是給系統(tǒng)狀態(tài)欄著色。當這個顏色和我們Activity中的Tool...
    chandarlee閱讀 15,607評論 2 54
  • 職責分工控制 要求根據(jù)企業(yè)目標和職能任務瑞躺,按照科學敷搪、精簡、高效的原則幢哨,合理設置職能部門和工作崗位赡勘,明確各部門、各崗...
    ecollab閱讀 1,157評論 0 1