Material Design 開發(fā)筆記 (持續(xù)更新...)

1. FitSystemWindow

在 layout 布局中設(shè)置 android:fitsSystemWindows="true" 到底發(fā)生了什么畦贸?
默認(rèn)的 View的行為是在該屬性設(shè)置后霎箍,系統(tǒng)通過在布局中預(yù)留出padding,使得布局有個(gè)相對(duì)的偏移舱权。特別的, 在頂層layout是 CoordinatorLayout 逾冬,DrawerLayout包吝,或是CollapsingToolbarLayout時(shí)锥余,這些layout (相比一般的布局腹纳,如FrameLayout) 已經(jīng)有了自定義的行為。

1.1 以 CoordinatorLayout 為例

if (ViewCompat.getFitsSystemWindows(this)) {
    if (mApplyWindowInsetsListener == null) {
        mApplyWindowInsetsListener =
            new androidx.core.view.OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View v,
                        WindowInsetsCompat insets) {
                    return setWindowInsets(insets);
                }
            };
    }
    // First apply the insets listener
    ViewCompat.setOnApplyWindowInsetsListener(this, mApplyWindowInsetsListener);

    // Now set the sys ui flags to enable us to lay out in the window insets
    setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

在5.0+系統(tǒng)中驱犹, 其方法setupForInsets()會(huì)檢測(cè) fitsSystemWindows屬性是否有設(shè)置過嘲恍,如果有,則設(shè)置當(dāng)前View的屬性為View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 然后進(jìn)一步調(diào)用dispatchApplyWindowInsetsToBehaviors雄驹,將WindowInsetsCompat 傳遞個(gè)也設(shè)置過fitsSystemWindows子view的Behavior class,直至WindowInsetsCompat被最終消費(fèi)掉(consumed)佃牛。

private WindowInsetsCompat dispatchApplyWindowInsetsToBehaviors(WindowInsetsCompat insets) {
    if (insets.isConsumed()) {
        return insets;
    }

    for (int i = 0, z = getChildCount(); i < z; i++) {
        final View child = getChildAt(i);
        if (ViewCompat.getFitsSystemWindows(child)) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final Behavior b = lp.getBehavior();

            if (b != null) {
                // If the view has a behavior, let it try first
                insets = b.onApplyWindowInsets(this, child, insets);
                if (insets.isConsumed()) {
                    // If it consumed the insets, break
                    break;
                }
            }
        }
    }

    return insets;
}   

1.2 Inset issue (e.g. Fragment transition)

在單Activity 多Fragment的UI結(jié)構(gòu)下,可能出現(xiàn)多個(gè)Fragment的布局都需要處理 Window insets的情況医舆。而實(shí)際上ViewGroup#dispatchApplyWindowInsets()默認(rèn)的實(shí)現(xiàn)中是會(huì)遍歷子View (DFS)俘侠,開始dispatch window insets 直至有子view消費(fèi)了insets。這就意味著彬向,一旦有子view消費(fèi)了insets兼贡,后續(xù)的子view就不會(huì)再有機(jī)會(huì)處理insets。

所以對(duì)應(yīng)的解決方法就是在Fragment的 Container中借助OnApplyWindowInsetsListener 改寫處理insets的機(jī)制娃胆。

fragment_container.setOnApplyWindowInsetsListener { view, insets ->
  var consumed = false

  (view as ViewGroup).forEach { child ->
    // Dispatch the insets to the child
    val childResult = child.dispatchApplyWindowInsets(insets)
    // If the child consumed the insets, record it
    if (childResult.isConsumed) {
      consumed = true
    }
  }

  // If any of the children consumed the insets, return
  // an appropriate value
  if (consumed) insets.consumeSystemWindowInsets() else insets
}

1.3 代碼實(shí)踐

  • 如果你使用了 CoordinatorLayout 或是 DrawerLayout,而且想要在system bars (包括status bar) 之下顯示 View等曼,可在其直接的子View中(遞歸地)指定android:fitsSystemWindows="true"里烦。

  • 對(duì)于當(dāng)前status Bar顏色的設(shè)置,一般地為了能讓自定義的view填充status bar的background區(qū)域禁谦,statusBarColor通常設(shè)置為transparent :
    Window#setStatusBarColor(int)
    或在Activity Theme中指定為:
    <item name="android:statusBarColor">@android:color/transparent</item>

  • 如果想要獲取status bar的高度胁黑,不必使用hardcoded value (24 dp) 或是讀取系統(tǒng)resource,可通過監(jiān)聽系統(tǒng) WindowInsets 實(shí)現(xiàn):

myView.setOnApplyWindowInsetsListener { view, insets ->
    val statusBarSize = insets.systemWindowInsetTop
    return insets
}

2. Fragment中添加 Option Menu

一般來說州泊,常見的對(duì)于ActionBar的處理是放在Host Activity中丧蘸。但根據(jù)特定的的UI設(shè)計(jì),F(xiàn)ragment中可能都有自定義的ActionBar遥皂,故將ActionBar的建立以及menu的響應(yīng)處理分散到各自的Fragment中力喷,這是更為內(nèi)聚的做法刽漂。

常見的在Fragment中使用Options Menu 需要注意:

2.1 啟用menu

在Fragment中設(shè)置setHasOptionsMenu(true)。

2.2 ActionBar 的對(duì)應(yīng)更新

由于其它Fragment中也有設(shè)置 menu弟孟,在切換Fragment后贝咙,當(dāng)前Activity關(guān)聯(lián)的的ActionBar可能已經(jīng)不是對(duì)應(yīng)到當(dāng)前的Fragment了,此時(shí)需要重新設(shè)置當(dāng)前的ActionBar :

// toolbar in current Fragment
setSupportActionBar(toolbar)

4. References

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拂募,一起剝皮案震驚了整個(gè)濱河市庭猩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌陈症,老刑警劉巖蔼水,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異录肯,居然都是意外死亡趴腋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門嘁信,熙熙樓的掌柜王于貴愁眉苦臉地迎上來于样,“玉大人,你說我怎么就攤上這事潘靖〈┢剩” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵卦溢,是天一觀的道長糊余。 經(jīng)常有香客問我,道長单寂,這世上最難降的妖魔是什么贬芥? 我笑而不...
    開封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮宣决,結(jié)果婚禮上蘸劈,老公的妹妹穿的比我還像新娘。我一直安慰自己尊沸,他們只是感情好威沫,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著洼专,像睡著了一般棒掠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屁商,一...
    開封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天烟很,我揣著相機(jī)與錄音,去河邊找鬼。 笑死雾袱,一個(gè)胖子當(dāng)著我的面吹牛恤筛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谜酒,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼叹俏,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了僻族?” 一聲冷哼從身側(cè)響起粘驰,我...
    開封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎述么,沒想到半個(gè)月后蝌数,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡度秘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年顶伞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剑梳。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唆貌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垢乙,到底是詐尸還是另有隱情锨咙,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布追逮,位于F島的核電站酪刀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钮孵。R本人自食惡果不足惜骂倘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巴席。 院中可真熱鬧历涝,春花似錦、人聲如沸漾唉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毡证。三九已至,卻和暖如春蔫仙,著一層夾襖步出監(jiān)牢的瞬間料睛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恤煞,地道東北人屎勘。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像居扒,于是被迫代替她去往敵國和親概漱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359