Android Design Support Library 的 代碼實(shí)驗(yàn)——幾行代碼,讓你的 APP 變得花俏

譯者地址:【翻】Android Design Support Library 的 代碼實(shí)驗(yàn)——幾行代碼成黄,讓你的 APP 變得花俏

原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session----Make your app fancy with few lines of code

原文項(xiàng)目 demo: Lab-Android-DesignLibrary

雙語對(duì)照地址: 【翻-雙語】Android Design Support Library 的 代碼實(shí)驗(yàn)——幾行代碼休弃,讓你的 APP 變得花俏

  • 翻譯: MrFu
  • 校驗(yàn): MrFu
  • 能去這里小小的點(diǎn)一下 star 嗎?非常感謝:Codelab

目前银受,我相信践盼,沒有任何 Android 開發(fā)者不知道材料設(shè)計(jì)的,因?yàn)樗脑O(shè)計(jì)在過去的一年震驚了世界宾巍,正式的變成了一個(gè)設(shè)計(jì)理念咕幻。

令人驚訝的是,在 Android 應(yīng)用中材料設(shè)計(jì)是不容易實(shí)現(xiàn)的顶霞,因?yàn)椴牧显O(shè)計(jì)的 UI 組件 如: Floating Action Button (FAB) 在低于 Android L 系統(tǒng)上是不可用的肄程。我們只能選擇使用由獨(dú)立開發(fā)者公布出來的第三方庫。

來了一個(gè)好消息选浑,上周(2015.5.29)在谷歌2015 I/O 大會(huì)時(shí)蓝厌,谷歌宣布了一個(gè)今年最讓人興奮的支持庫,名叫 Android Design Support Library古徒,在這個(gè)單獨(dú)的 library 里提供了一堆有用的材料設(shè)計(jì) UI 組件拓提。通過這篇文章,讓我用這個(gè)機(jī)會(huì)向你一個(gè)一個(gè)描述如何來使用他們隧膘。

請(qǐng)查看下面這個(gè)視頻作為本教程最終的結(jié)果代态。

0
0

從這里開始,空白 Activity 里面有一個(gè) DrawerLayout 疹吃。

1
1

Activity 已經(jīng)調(diào)整為材料設(shè)計(jì)風(fēng)格的主題蹦疑。

<item name="colorPrimary">#2196F3</item>
<item name="colorPrimaryDark">#1565C0</item>
<item name="colorAccent">#E91E63</item>

好了,讓我們開始吧互墓!

步驟一:從 Github 上拷貝源碼

我已經(jīng)為這個(gè) codelab 準(zhǔn)備了源碼必尼,你可以從 GitHub 輕松的 clone 它篡撵。MainActivity 是上面所示的最終結(jié)果。請(qǐng)?jiān)谶@個(gè) project 的 CodeLabActivity 中做我們的代碼實(shí)驗(yàn)育谬。

你一定要自己做的一個(gè)任務(wù)是... 成功的運(yùn)行它,它應(yīng)該是通過簡(jiǎn)單的點(diǎn)擊“運(yùn)行”按鈕來完成锰镀。

步驟二:添加 Android Design Support Library 依賴

第一件要做的事是在我們的項(xiàng)目中添加 Android Design Support Library,在 app 的 build.gradle 文件下添加一行依賴代碼憾筏。

compile 'com.android.support:design:22.2.0'

`
請(qǐng)注意 Design Support Library 依賴于 Support v4 和 AppCompat v7花鹅。一旦你在你的項(xiàng)目中添加這個(gè) library,你也將獲得一個(gè)這些 libraries 的組件的入口古拴。(譯者注:就是說 Design Support Library 中就已經(jīng)包含了 Support v4 和 AppCompat v7)

順便說一下,從 Github 克隆的源碼已經(jīng)添加了上面這行代碼真友。但是如果你創(chuàng)建了你自己的項(xiàng)目黄痪,你需要自己添加它。

步驟三:添加 FAB

Floating Action Button (FAB) 是一個(gè)有一些陰影的圓形按鈕盔然,這個(gè)令人難以置信的桅打,可以改變世界的設(shè)計(jì)。毫不奇怪它為什么會(huì)變成材料設(shè)計(jì)的標(biāo)志轻纪。因此我們從這開始油额。添加一個(gè) FAB 在布局文件叠纷,因?yàn)樗枰恍└割悂硎顾谄聊坏挠蚁路轿恢脤?duì)齊刻帚,所以用 FrameLayout 來包裹 FloatingActionButton。請(qǐng)做這樣的事情作為 DrawerLayout 的內(nèi)容:更換 activity_code_lab.xml 中已經(jīng)存在的 TextView 涩嚣,像下面的代碼這樣崇众。

<android.support.v4.widget.DrawerLayout ...
    xmlns:app="http://schemas.android.com/apk/res-auto"
    ....>
    <FrameLayout
        android:id="@+id/rootLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fabBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|right"
            android:src="@drawable/ic_plus"
            app:fabSize="normal" />
    </FrameLayout>
    ...
</android.support.v4.widget.DrawerLayout>

android:src 是用來定義你想要的資源文件 ID(推薦 40dp 的清晰的 png 文件),而 app:fabSize="normal" 是用來定義 FAB 的大小的航厚,normal 的意思是在大多數(shù)情況下標(biāo)準(zhǔn)尺寸為 56dp 的按鈕顷歌,但是萬一你想使用較小的一個(gè), mini 是另一個(gè)選擇幔睬,它的大小將變成 40dp眯漩。

就這樣麻顶,F(xiàn)AB 現(xiàn)在準(zhǔn)備使用辅肾!下面是當(dāng)我在 Android 4.4 上運(yùn)行這段代碼的結(jié)果矫钓。

p0
p0

但是當(dāng)我們運(yùn)行在 Android 5.0 上時(shí),結(jié)果變成了這樣...

p1
p1

這不是特效既绩,只是一個(gè) bug熬词。幸運(yùn)的是 design library 的開發(fā)者團(tuán)隊(duì)已經(jīng)知道這個(gè)問題并在不久的將來會(huì)發(fā)布一個(gè)修復(fù)的版本互拾。但是如果你現(xiàn)在想要使用它颜矿,我們可以做一些事情:通過設(shè)置 FAB 的 margin right 和 margin bottom 為 16dp 在 API Level 21+ 上面并在 低于 Android L 的版本上 設(shè)置為 0dp骑疆。感謝配置資源可以讓我們非常容易的做到這一點(diǎn)箍铭。

res/values/dimens.xml

<dimen name="codelab_fab_margin_right">0dp</dimen>
<dimen name="codelab_fab_margin_bottom">0dp</dimen>

res/values-v21/dimens.xml

<dimen name="codelab_fab_margin_right">16dp</dimen>
<dimen name="codelab_fab_margin_bottom">16dp</dimen>

res/layout/activity_code_lab.xml

<android.support.design.widget.FloatingActionButton
    ...
    android:layout_marginBottom="@dimen/codelab_fab_margin_bottom"
    android:layout_marginRight="@dimen/codelab_fab_margin_right"
    .../>

好了诈火!

p2
p2

這里有另一個(gè) bug冷守。陰影,你在哪里馆截?這個(gè) bug 和先前的那個(gè)是有關(guān)聯(lián)的混卵。你可以通過定義 app:borderWidth="0" 作為 FAB 的屬性 作為一個(gè)快速的解決方案淮菠。

p3
p3

歡迎回來合陵,陰影拥知!其深度是自動(dòng)設(shè)置的最佳實(shí)踐之一:6dp 在空閑狀態(tài)低剔,12dp 是按下狀態(tài)姻锁。反正你可以通過定義重寫這些值位隶,app:elevation 為空閑狀態(tài)下的陰影深度涧黄,andapp:pressedTranslationZ 為按下狀態(tài)的笋妥。

關(guān)于按鈕的顏色春宣,F(xiàn)AB 基本上使用強(qiáng)調(diào)色信认,但是你可以重寫 app:backgroundTint 屬性來修改。

就像傳統(tǒng)的按鈕油挥,你可以通過 setOnClickListener() 處理點(diǎn)擊深寥,在 CodeLabActivity.java 文件的 initInstances 方法中添加下面的代碼惋鹅。

FloatingActionButton fabBtn;
...
private void initInstances() {
    ...
    fabBtn = (FloatingActionButton) findViewById(R.id.fabBtn);
    fabBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    });
}

完成闰集!

步驟四:使用 Snackbar

Snackbar武鲁,在屏幕的地步一個(gè)微小的黑色條顯示著一條簡(jiǎn)短的消息挚瘟,在這個(gè) library 中也是可用的乘盖。Snackbar 和 Toast 有著相同的概念侧漓,但是不同于 Toast布蔗,它的表現(xiàn)是作為 UI 的一部分而不是覆蓋在屏幕上纵揍。

p4
p4

不只是概念相同泽谨,編碼風(fēng)格也是由 Toast 所啟發(fā),你可以通過下面的代碼喚起 Snackbar涂身。

Snackbar.make(someView, "Hello. I am Snackbar!", Snackbar.LENGTH_SHORT)
        .setAction("Undo", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        })
        .show();

make() 的第一個(gè)參數(shù)是一個(gè) View 或者 Layout丁鹉,你想在它的底部位置顯示一個(gè) Snackbar揣钦。在這個(gè)例子中冯凹,一個(gè) FrameLayout 包裹著一個(gè) FAB 就是其中一個(gè)例子宇姚。setAction() 方法是用在設(shè)置動(dòng)作顯示在 Snackbar 的右側(cè)并有對(duì)應(yīng)的監(jiān)聽嚎花。這個(gè)方法不是必需的紊选,可以移除兵罢。

現(xiàn)在卖词,讓我們通過添加下面的代碼去試試此蜈。

FrameLayout rootLayout;
...
private void initInstances() {
    ...
    rootLayout = (FrameLayout) findViewById(R.id.rootLayout);
    fabBtn = (FloatingActionButton) findViewById(R.id.fabBtn);
    fabBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(rootLayout, "Hello. I am Snackbar!", Snackbar.LENGTH_SHORT)
                    .setAction("Undo", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                        }
                    })
                    .show();
        }
    });
}

點(diǎn)擊 FAB 以及看到的結(jié)果。

p5
p5

有用战授!但是... 還不是很完美植兰。它是出現(xiàn)在放置 Snackbar 頂部的位置楣导,長(zhǎng)期的用戶體驗(yàn)是很差的爷辙。不管怎么樣,這個(gè)行為已經(jīng)是正確的务冕,因?yàn)檫@里沒有為 Snackbar 和 FAB 定義任何關(guān)聯(lián)禀忆。

為了這個(gè)目的專門發(fā)明了一個(gè)特殊的布局离熏,使子 Views 協(xié)調(diào)工作滋戳。這就不用奇怪為什么它的名字是 CoordinatorLayout 了奸鸯。

步驟五:使他們和 CoordinatorLayout 協(xié)作

CoordinatorLayout 是一個(gè)讓子 Views 協(xié)調(diào)工作的布局娄涩。這里沒有任何魔法蓄拣。每個(gè) View 中肯定是設(shè)計(jì)和實(shí)現(xiàn)了和 CoordinatorLayout 協(xié)同工作的弯蚜。FAB 和 Snackbar 就是這兩個(gè)view碎捺。

所以... 現(xiàn)在讓我們將 FrameLayout 改成 CoordinatorLayout 包裹一個(gè)FAB。

res/layout/activity_code_lab.xml

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.FloatingActionButton
        ... />
</android.support.design.widget.CoordinatorLayout>

而且诵叁,不要忘了在 CodeLabActivity.java 改變 rootLayout 的變量類型為 CoordinatorLayout拧额,否則就會(huì)崩潰侥锦。

//FrameLayout rootLayout;
CoordinatorLayout rootLayout;
//rootLayout = (FrameLayout) findViewById(R.id.rootLayout);
rootLayout = (CoordinatorLayout) findViewById(R.id.rootLayout);

結(jié)果:現(xiàn)在 FAB 隨著 Snackbar 的出現(xiàn)和消失而移動(dòng)恭垦。還增加了一些功能唠帝。Snackbar 現(xiàn)在能夠滑動(dòng)消失了襟衰!請(qǐng)?jiān)囈辉嚒?/p>

2
2

但是 bug 到處都是… bug 出現(xiàn)在低于 Android L 的系統(tǒng)上瀑晒,當(dāng) Snackbar 滑動(dòng)消失的時(shí)候,F(xiàn)AB 忘記了移動(dòng)下來映砖。

3
3

這顯然是一個(gè) bug竹宋,但是我不知道確切的原因心褐。感謝天主莫矗,這里有一些解決方法三娩。從我的實(shí)驗(yàn)中雀监,我發(fā)現(xiàn)當(dāng)我們?cè)O(shè)置 FAB 的 margin bottom 和 margin right 為一些非零的正數(shù)值時(shí)会前,它將會(huì)奇跡般的正常工作瓦宜,所以..就只需要為低于 Android L 的系統(tǒng)改變 margin 的值為 0.1dp就行歉提。

res/values/dimens.xml

<dimen name="codelab_fab_margin_right">0.1dp</dimen>
<dimen name="codelab_fab_margin_bottom">0.1dp</dimen>

完成苔巨。下面是結(jié)果侄泽。

4
4

從現(xiàn)在起悼尾,如果你計(jì)劃使用 Android Design Support Library闺魏。請(qǐng)首先考慮 CoordinatorLayout,因?yàn)樗拖袷沁@個(gè) library 的核心艰垂。

步驟六:再見 ActionBar,你好娩怎,Toolbar

Toolbar 不是 Android Design Support Library 的一部分截亦,而是在這個(gè)庫中需要與其他組件一起使用崩瓤。

Toolbar 是一個(gè)替代傳統(tǒng)的 Action Bar 具有更靈活的行為。我鼓勵(lì)你們從現(xiàn)在開始隱藏 Action Bar 并且切換到 Toolbar肾扰。因?yàn)檫@些有奇妙功能的新庫集晚,包括 Design Support Library 的組件中偷拔,都被設(shè)計(jì)為和 Toolbar 協(xié)同工作而不是 Action Bar欺旧。

很容易切換到 Toolbar辞友。只需要從 Activity 定義的 AppTheme 的 style 屬性隱藏掉 Action Bar 開始称龙。

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

然后在 CoordinatorLayout 里面的 FAB 之前正確的放一個(gè) Toolbar 組件鲫尊。

<android.support.design.widget.CoordinatorLayout
    ...>
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
    <android.support.design.widget.FloatingActionButton
        ...>
    </android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>

現(xiàn)在寫代碼來告訴系統(tǒng),我們將使用 Toolbar 作為一個(gè) Action Bar扛施,更換下面的 Java 代碼疙渣。

Toolbar toolbar;
private void initInstances() {
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ...
}

雖然它現(xiàn)在可以運(yùn)行成功泼菌,但是根據(jù)我之前說的哗伯,放在 CoordinatorLayout 的東西必須被設(shè)計(jì)和實(shí)現(xiàn)成與它一起合作的焊刹,否則將不與任何其他兄弟 views(sibling views) 協(xié)作虐块。但是... Toolbar是不合適的贺奠。別擔(dān)心挂据,這里沒有任何新的特殊 Toolbar崎逃。只是一個(gè)組件是為了準(zhǔn)備讓 Toolbar 與 CoordinatorLayout 一起工作的更加完美婚脱。這是簡(jiǎn)單的任務(wù),只是簡(jiǎn)單的用 AppBarLayout 包裹 Toolbar吟宦,就這樣殃姓!

<android.support.design.widget.CoordinatorLayout
    ...>
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
       <android.support.v7.widget.Toolbar
           .../>
    </android.support.design.widget.AppBarLayout>
    <android.support.design.widget.FloatingActionButton
        ...>
    </android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>

現(xiàn)在運(yùn)行和測(cè)試蜗侈,如果你做的都是對(duì)的踏幻,你將會(huì)看到 Drawer Menu 會(huì)覆蓋在 App Bar區(qū)域的頂部该面。使用了 AppBarLayout 的輸出結(jié)果是:低于應(yīng)用欄區(qū)域的陰影現(xiàn)在回來了隔缀,耶!(譯者注:不曉得怎么翻了:The outgrowth of applying AppBarLayout is the drop shadow below App Bar area is now returned ! Yah !)

5
5

這個(gè)步驟現(xiàn)在完成了牵触。從現(xiàn)在開始荒吏,我建議你總是用 AppBarLayout 包裹 ToolBar 元素绰更。光憑它能帶回來陰影的能力就足夠有說服力儡湾。

步驟7:在內(nèi)容區(qū)域放東西

我們已經(jīng)得到了 FAB 和 Toolbar徐钠,現(xiàn)在是時(shí)候在 Activity 的內(nèi)容區(qū)域放上東西了尝丐。

額远荠。如果是兩個(gè)簡(jiǎn)單的按鈕呢譬淳?好吧邻梆,讓我們把它們放在在 AppBarLayout 和 FAB 之間浦妄。

    ...
</android.support.design.widget.AppBarLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Yo Yo"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Yo Yo"/>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
    ...>

下面是結(jié)果...

p6
p6

這些按鈕似乎都出人意料的放在了 Toolbar 下面。猜猜為什么宜咒?

是的故黑,一些古老的原因场晶,LinearLayout 沒有被設(shè)計(jì)成與 CoordinatorLayout 協(xié)同工作诗轻。在這樣的情況下扳炬,沒有任何布局用來包裹 LinearLayout恨樟,使它像 Toolbar 的做法那樣劝术。但它是更加容易的衬吆,你只需要在 LinearLayout 添加一個(gè)屬性告訴它的滾動(dòng)行為咆槽,就像下面寫的這樣:

<LinearLayout
    ...
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    ...>

現(xiàn)在,他們被放在了正確的位置了蛾娶,耶蛔琅!

p7
p7

完成罗售!=)

步驟8:玩轉(zhuǎn) TabLayout

Tab 是在 Android 應(yīng)用程序中用戶體驗(yàn)(UX)最佳實(shí)踐的一部分寨躁。在以前,如果我們想要使用新的材料設(shè)計(jì)風(fēng)格的 Tab方面,我們需要自己去為項(xiàng)目中下載 SlidingTabLayout 和 SlidingTabStrip 的源碼〔儋鳎現(xiàn)在颓屑,我們只需要使用這個(gè)庫提供的 TabLayout邢锯,它也有很多可以調(diào)整的選項(xiàng)丹擎。

我們應(yīng)該把 TabLayout 放在哪里蒂培?根據(jù) Android 應(yīng)用程序用戶體驗(yàn)指導(dǎo)原則翎冲,Tab 應(yīng)該放在屏幕的頂部而不是在底部抗悍。還有缴渊,它應(yīng)該在陰影部分的上面衔沼。所以指蚁,我們將其放在 AppBarLayout 里面凝化,沿著 Toolbar。這是可以做到的袜蚕,因?yàn)?AppBarLayout 是繼承自一個(gè)垂直的 LinearLayout遣疯。

<android.support.design.widget.AppBarLayout ...>
    <android.support.v7.widget.Toolbar ... />
    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>

在 Java 代碼中添加一些 tabs缠犀。

TabLayout tabLayout;
private void initInstances() {
    tabLayout = (TabLayout) findViewById(R.id.tabLayout);
    tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
    tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
    tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
    ...
}

下面是結(jié)果:

p8
p8

背景色會(huì)自動(dòng)設(shè)置成 primary color(主題色)虐急,而導(dǎo)航線的顏色是強(qiáng)調(diào)色止吁。但是你將會(huì)注意到 Tab 的字體仍然是黑色的敬惦,但是我們希望字體是白色的俄删。這是因?yàn)槲覀冞€沒有為 TabLayout 提供任何主題呢畴椰。TabLayout 定義主題是簡(jiǎn)單的迅矛,就像這樣:

<android.support.design.widget.TabLayout
    ...
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

現(xiàn)在,他們是白色的了威兜。

p9
p9

你可以像上面這樣選擇手動(dòng)控制 TabLayout椒舵,或者讓它和 ViewPager 一起工作笔宿,自動(dòng)調(diào)用 setupWithViewPager(...)。我相信這種情況會(huì)很頻繁的使用迈勋。

還有重归,我們可以調(diào)整兩個(gè)屬性來顯示 TabLayout。

app:tabMode - 如果你想在屏幕上顯示出每個(gè)單獨(dú)的 tab育苟,就設(shè)置 tab 為 fixed 的, 拓哺。它適合只有少數(shù) tab 的時(shí)候闲孤,但是如果有很多的 tab 的時(shí)候這是一個(gè)完全錯(cuò)誤的選擇讼积。在這種情況下你是不確定所有的 tab 是否能很好的在同一時(shí)間顯示出來的勤众。所以们颜,你可以設(shè)置這個(gè)屬性為 scrollable 讓用戶去滾動(dòng) tab窥突,就像 Google Play Store 那樣。

app:tabGravity - 如果你想要分配所有的可用空間給每個(gè) tab沦疾,就設(shè)置這個(gè)屬性為 fill刨秆。如果你想要所有的 tab 在屏幕的中間坛善,就設(shè)置這個(gè)屬性為 center剔交。請(qǐng)注意岖常,如果 tabMode 是設(shè)置成 scrollable 的竭鞍,則這個(gè)屬性將會(huì)被忽略偎快。

每個(gè)模式的樣子就像下面這樣:

p10
p10

TabLayout 完成了!

步驟9:當(dāng)隨著內(nèi)容滾動(dòng)時(shí)丐怯,讓 AppBarLayout 退出屏幕

一個(gè)優(yōu)美的 Android 用戶體驗(yàn)是引導(dǎo) App Bar 可以隨著內(nèi)容滾動(dòng)出屏幕的读跷,以獲得額外的空間來顯示內(nèi)容效览,并且钦铺,這已經(jīng)是被證明這樣的用戶體驗(yàn)是很棒的。以前有一些應(yīng)用程序已經(jīng)實(shí)現(xiàn)了這種行為烫映,但是開發(fā)者必須自己來實(shí)現(xiàn)。現(xiàn)在它只需要用一行代碼就能輕松的完成识补。

首先祝辣,我們需要讓內(nèi)容能夠滾動(dòng)蝙斜,先往 LinearLayout 加入一些 Button孕荠。大約20個(gè)弯予?

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Yo Yo"/>
...
<!-- Add 20 more buttons here -->
...
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Yo Yo"/>

然后用 ScrollView 包裹這個(gè) LinearLayout锈嫩,還有祠挫,不要忘了將 LinearLayout 里的 layout_behavior 移動(dòng)到 ScrollView等舔,因?yàn)楝F(xiàn)在 ScrollView 是 CoordinatorLayout的最直接的子 view慌植。

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        ...
    </LinearLayout>
</ScrollView>

然后給 Toolbar 添加一個(gè)滾動(dòng)標(biāo)志,就像這樣:

<android.support.v7.widget.Toolbar
    ...
    app:layout_scrollFlags="scroll|enterAlways" />

試試吧

6
6

額... 原先假定的 Toolbar 會(huì)隨著內(nèi)容的滾動(dòng)滾出屏幕的交汤,但是為什么它看起來什么都沒有實(shí)現(xiàn)呢芙扎?

同樣的老原因啦... ScrollView 沒有被設(shè)計(jì)成與 CoordinatorLayout 協(xié)同工作(又來)戒洼。你需要另一個(gè) view:NestedScrollView圈浇,Android Support Library v4 中有提供磷蜀。這個(gè) NestedScrollView 設(shè)計(jì)出來的目的就是為了與 CoordinatorLayout 協(xié)同工作的怎茫。

<android.support.v4.widget.NestedScrollView ...>
    <LinearLayout ...>
        ...
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

同樣的原因轨蛤,請(qǐng)注意了: ListView 類也是和 CoordinatorLayout 不能協(xié)同工作的祥山。只有 RecyclerView 可以缝呕。也許需要時(shí)間來改變咯~

這里將 ScrollView 改變成 NestedScrollView 后的結(jié)果供常。

7
7

運(yùn)行起來真贊!你會(huì)注意到 Toolbar 滾出了屏幕源祈,但是 TabLayout 仍然還在香缺。這是因?yàn)槲覀儧]有給 TabLayout 設(shè)置任何滾動(dòng)標(biāo)志图张。如果你想要 TabLayout 同樣從屏幕上消失埂淮,只需要給 TabLayout 定義相同的屬性就可以了。

<android.support.design.widget.TabLayout
    ...
    app:layout_scrollFlags="scroll|enterAlways" />

結(jié)果:

8
8

這里會(huì)有一些手勢(shì)上的 bug慕趴。我發(fā)現(xiàn)拉它回到屏幕是非常困難的冕房“也幔看來我們得等下一個(gè)版本了帝际。

現(xiàn)在蹲诀,讓我們來看看它的一些細(xì)節(jié)脯爪。很好奇這些標(biāo)志的真實(shí)意思是什么:scrollenterAlways痕慢?事實(shí)上我們可以在這里設(shè)置4個(gè)屬性值。

scroll - 你想你想要設(shè)置這個(gè) view 隨著內(nèi)容滾動(dòng)拇泛,你需要應(yīng)用這個(gè)標(biāo)志俺叭。

enterAlwaysCollapsed - 這個(gè)標(biāo)志定義了 View 是如何回到屏幕的。當(dāng)你的 view 已經(jīng)聲明了一個(gè)最小高度(minHeight) 并且你使用了這個(gè)標(biāo)志裕照,你的 View 只有在回到這個(gè)最小的高度的時(shí)候才會(huì)展開晋南,只有當(dāng) view 已經(jīng)到達(dá)頂部之后它才會(huì)重新展開全部高度负间。滾動(dòng)標(biāo)志像這樣來使用它:scroll|enterAlwaysCollapsed政溃。

9
9

它好像在這個(gè) minHeight 部分死活不工作扼鞋。這里和 TabLayout 有另一個(gè)問題云头。很難把這些 View 拉回到屏幕來盘寡。

enterAlways - 這個(gè)標(biāo)志確保了任何向下滾動(dòng)的操作都會(huì)讓這個(gè) view 變得可見竿痰,達(dá)到“快速返回”(‘quick return’ )的效果影涉,滾動(dòng)標(biāo)志像這樣來使用它: scroll|enterAlways

10
10

exitUntilCollapsed - View 將關(guān)閉滾動(dòng)直到它被折疊起來(有 minHeight) 并且一直保持這樣,舉個(gè)例子:

<android.support.v7.widget.Toolbar
    ...
    android:layout_height="192dp"
    android:gravity="bottom"
    android:paddingBottom="12dp"
    android:minHeight="?attr/actionBarSize"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"/>

下面是上述代碼的結(jié)果:

11
11

這種模式在組件中經(jīng)常使用,我將在下一個(gè)部分討論豁陆。

步驟10: 移除 TabLayout

從實(shí)驗(yàn)來看盒音,在上述情況下當(dāng)我們用 TabLayout 來滾動(dòng)的時(shí)候,有一些明顯的 bug雄坪。我相信這只是一個(gè) bug诸衔,而且以后會(huì)被修復(fù)的。現(xiàn)在谒亦,讓我們首先從代碼中移除 TabLayout份招,確保下一步運(yùn)行是流暢的。

<!--android.support.design.widget.TabLayout -->

從 Java 代碼中也刪除

//tabLayout = (TabLayout) findViewById(R.id.tabLayout);
//tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
//tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
//tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));

好了谐腰,讓我們?nèi)プ鱿乱徊剑?/p>

Step 11: Make Toolbar collapsable 步驟11:使工具欄可折疊

就像在 exitUntilCollapsed 部分所示的例子中,Toolbar 可以展開和折疊砸西,但是你會(huì)看到它還不是很完美芹枷。Toolbar 仍然離開了屏幕,最好的體驗(yàn)是讓這些 icon (漢堡等-即菜單欄) 應(yīng)該留在屏幕內(nèi)蝶涩。

Design Support Library 已經(jīng)為這個(gè)準(zhǔn)備好了。用 CollapsingToolbarLayout 你可以像魔術(shù)一樣讓 Toolbar 折疊起來熄攘,就像其他組件一樣挪圾,它是非常容易使用的洼畅,具體操作步驟如下:

  • CollapsingToolbarLayout 包裹 Toolbar棚赔,但仍然在 AppBarLayout

  • Toolbar 中刪除 layout_scrollFlags

  • CollapsingToolbarLayout 聲明 layout_scrollFlags帝簇,并且將 layout_scrollFlags 設(shè)置成 scroll|exitUntilCollapsed

  • 改變 AppBarLayout 擴(kuò)張狀態(tài)時(shí)的布局高度大小。在這個(gè)例子中靠益,我用 256dp

這是最終代碼丧肴。

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="256dp">
    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsingToolbarLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

這個(gè)結(jié)果是:

12
12

看起來不錯(cuò),但是這些 Toolbar icons 仍然滾出了屏幕胧后。我們可以聲明這個(gè)屬性給 Toolbar 來固定住它芋浮,讓它總是在屏幕的頂部何暇。

<android.support.v7.widget.Toolbar
    ...
    app:layout_collapseMode="pin"/>

Toolbar現(xiàn)在被定住了!

13
13

但是,等一下…標(biāo)題的文字在哪里?!不幸的是艰管,在用 CollapsingToolbarLayout 包裹住 Toolbar 后缸浦,它隨風(fēng)而逝了。我們必須通過在 Java 代碼中手動(dòng)設(shè)置 setTitle(String) 來實(shí)現(xiàn)。

CollapsingToolbarLayout collapsingToolbarLayout;
private void initInstances() {
    ...
    collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsingToolbarLayout);
    collapsingToolbarLayout.setTitle("Design Library");
}

結(jié)果:

14
14

這里的字體顏色仍然是黑的的铃绒。這是因?yàn)槲覀冞€沒有為 App Ba 設(shè)置任何主題。要做到這一點(diǎn),只需要簡(jiǎn)單的為 AppBarLayout 聲明 android:theme 屬性就可以了,就像這樣:

<android.support.design.widget.AppBarLayout
    ...
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

現(xiàn)在,標(biāo)題變成了白色的了啥纸!

15
15

由于CollapsingToolbarLayout 的 特點(diǎn)荣暮,應(yīng)用的標(biāo)題文字在收縮和展開狀態(tài)是會(huì)自動(dòng)過渡的。如果你想要在展開狀態(tài)改變標(biāo)題文字的位置,你可以這樣做:通過應(yīng)用的 margin 的4個(gè)屬性,就是:app:expandedTitleMargin, app:expandedTitleMarginBottom, app:expandedTitleMarginEnd 以及 app:expandedTitleMarginStart

或者如果你想要在折疊和展開狀態(tài)時(shí)改變文本的顯示。你可以這樣來簡(jiǎn)單的實(shí)現(xiàn):設(shè)置 TextAppearance,分別通過 app:collapsedTitleTextAppearanceapp:expandedTitleTextAppearance 來設(shè)置。

讓我們從試著改變 margin 為64dp 開始。

<android.support.design.widget.CollapsingToolbarLayout
    ...
    app:expandedTitleMarginStart="64dp">

結(jié)果:

16
16

真棒!

步驟12:為 App Bar 添加背景圖片

在這種情況下,我們想要用一張美麗的圖片作為 App Bar 的背景,而不只是像現(xiàn)在這樣的一個(gè)普通的顏色。幸運(yùn)的是 CollapsingToolbarLayout 是繼承自 FrameLayout 所以我們可以輕松的添加一個(gè) ImageView 作為 Toolbar 的背景圖層,就像這樣:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/header" />
<android.support.v7.widget.Toolbar
    ...

結(jié)果:

17
17

圖片已經(jīng)顯示出來了帖烘,但是這里有一點(diǎn)還沒有達(dá)到預(yù)期,藍(lán)色的導(dǎo)航條仍舊顯示著。有一個(gè) Toolbar 的背景看起來不是酷炫的。從 Toolbar 移除它,只需要下面這行代碼就行了。

android:background="?attr/colorPrimary"

結(jié)果:

18
18

現(xiàn)在圖片是隨著內(nèi)容的滾動(dòng)了摹恨,但是看起來太呆了寝凌。我們可以使用視差模式讓它變得更優(yōu)雅一些青柄,只需要聲明 collapse 就行了虹蒋,像下面這樣:

<ImageView
   ...
   app:layout_collapseMode="parallax" />

結(jié)果:

19
19

你也可以設(shè)置視差的系數(shù)邪驮,介于 0.0-1.0之間喻粹。

app:layout_collapseParallaxMultiplier="0.7"

請(qǐng)你自己去嘗試一下=)

最后你可能會(huì)注意到 App Bar 的背景總顯示一張圖片查乒。你可以讓它在收縮的時(shí)候自動(dòng)的變化到普通的顏色,通過聲明屬性 app:contentScrim 像下面這樣來實(shí)現(xiàn):

<android.support.design.widget.CollapsingToolbarLayout
    ...
    app:contentScrim="?attr/colorPrimary">

結(jié)果:

20
20

只用了幾行代碼瘸彤,就讓 App Bar 變得這么漂亮了 =)

步驟13:玩轉(zhuǎn) Navigation Drawer

現(xiàn)在從左側(cè)拉出 Drawer Menu 仍然只是一個(gè)空白的面板拯杠。在以前,實(shí)現(xiàn)這個(gè)菜單是非常麻煩的枝秤,因?yàn)槲覀儾坏貌皇謩?dòng)的用 LinearLayout 或者 ListView 去實(shí)現(xiàn)菌赖。

在 Android Design Support Library 中提供了 NavigationView,實(shí)現(xiàn)它變得更容易了到逊,它為我們節(jié)省了15.84321倍的時(shí)間铜靶!

首先,為 Drawer Menu 創(chuàng)建一個(gè)標(biāo)題視頻布局文件嚼吞。(它已經(jīng)在 Github的項(xiàng)目中了)

res/layout/nav_header.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/nav_header_bg"
        android:scaleType="centerCrop" />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/nuuneoi"
        android:layout_gravity="bottom"
        android:layout_marginBottom="36dp" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="16dp"
        android:text="nuuneoi"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</FrameLayout>

現(xiàn)在創(chuàng)建一個(gè)菜單資源文件

res/menu/navigation_drawer_items.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="all">
        <item
            android:id="@+id/navItem1"
            android:icon="@drawable/ic_action_location_found_dark"
            android:title="Home"/>
        <item
            android:id="@+id/navItem2"
            android:icon="@drawable/ic_action_location_found_dark"
            android:title="Blog"/>
        <item
            android:id="@+id/navItem3"
            android:icon="@drawable/ic_action_location_found_dark"
            android:title="About"/>
        <item
            android:id="@+id/navItem4"
            android:icon="@drawable/ic_action_location_found_dark"
            android:title="Contact"/>
    </group>
</menu>

NavigationView 與兩個(gè)資源文件綁定起來俏脊,作為 Drawer Menu 的菜單區(qū)域漫萄,用下面的代碼來替換一個(gè)已經(jīng)存在的 白色的 LinearLayout :

        ...
    </android.support.design.widget.CoordinatorLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:itemIconTint="#333"
        app:itemTextColor="#333"
        app:menu="@menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>

現(xiàn)在:召喚 Drawer Menu启昧!哇喔,哇喔

21
21

NavigationView 就是為了 Drawer Menu 而特別設(shè)計(jì)的座柱。所以景用,所有的東西都會(huì)被創(chuàng)建并且自動(dòng)測(cè)量包括菜單的寬度等舀瓢,我們自己定義案例來配置以前的設(shè)計(jì)。

為了處理這些菜單項(xiàng)的點(diǎn)擊事件赶袄,你可以聲明 setNavigationItemSelectedListener 來監(jiān)聽颜说,就像下面這樣:

NavigationView navigation;
private void initInstances() {
    ...
    navigation = (NavigationView) findViewById(R.id.navigation);
    navigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) {
            int id = menuItem.getItemId();
            switch (id) {
                case R.id.navItem1:
                    break;
                case R.id.navItem2:
                    break;
                case R.id.navItem3:
                    break;
            }
            return false;
        }
    });
}

在實(shí)際使用中乾吻,請(qǐng)隨意的區(qū)聲明你想要定義的 header view 和修改菜單項(xiàng)。

步驟14:用上 TextInputLayout 讓 EditText 變的更風(fēng)騷

這是 Codelab 的最后一部分了扭勉。你可以改變一個(gè)舊的 EditText 的風(fēng)格,讓它變得更時(shí)髦,即:總是會(huì)顯示一個(gè)提示或者一個(gè)錯(cuò)誤信息遣鼓。

要做到這一點(diǎn),只需要簡(jiǎn)單的用 TextInputLayout 包裹住一個(gè) EditText 堵第,就這么簡(jiǎn)單也搓!

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Username" />
</android.support.design.widget.TextInputLayout>

把這兩個(gè)控件放到 NestedScrollView 里看下結(jié)果。

22
22

難以置信的容易吧宇挫?=)

結(jié)論

Android Design Support Library 是非常有前途的支持庫欣除,它非常值得在你的產(chǎn)品上使用墨辛。雖然它仍然包含了很多錯(cuò)誤磨淌,我建議你再等等,直到每個(gè)錯(cuò)誤都被修復(fù)堵幽。

這么長(zhǎng)的教程,希望希望你覺得它有用 =)

`


p11
p11

Author: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory)
A full-stack developer with more than 6 years experience on Android Application Development and more than 12 years in Mobile Application Development industry. Also has skill in Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Training, Public Speaking and do love to share things to people in the world!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扼雏,一起剝皮案震驚了整個(gè)濱河市茎匠,隨后出現(xiàn)的幾起案子汽馋,更是在濱河造成了極大的恐慌悄雅,老刑警劉巖放案,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異神帅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門雇寇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來深滚,“玉大人皂贩,你說我怎么就攤上這事轰枝∈傺蹋” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵谍失,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)宛琅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任介牙,我火速辦了婚禮办素,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己废菱,他們只是感情好芋哭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著骤坐,像睡著了一般僧著。 火紅的嫁衣襯著肌膚如雪搓逾。 梳的紋絲不亂的頭發(fā)上寸爆,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音奔滑,去河邊找鬼艾岂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛朋其,可吹牛的內(nèi)容都是我干的王浴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼梅猿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼氓辣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袱蚓,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤钞啸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后喇潘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體体斩,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年颖低,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了絮吵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忱屑,死狀恐怖蹬敲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莺戒,我是刑警寧澤伴嗡,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脏毯,受9級(jí)特大地震影響闹究,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜食店,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一渣淤、第九天 我趴在偏房一處隱蔽的房頂上張望赏寇。 院中可真熱鬧,春花似錦价认、人聲如沸嗅定。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渠退。三九已至,卻和暖如春脐彩,著一層夾襖步出監(jiān)牢的瞬間碎乃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工惠奸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梅誓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓佛南,卻偏偏與公主長(zhǎng)得像梗掰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嗅回,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,161評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc及穗,orm框架 https://github.com/yangf...
    passiontim閱讀 15,434評(píng)論 2 45
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,762評(píng)論 22 665
  • 睡了一覺起來發(fā)現(xiàn) 又有一個(gè)大學(xué)同學(xué)今天扯證了 哎 都這么迅速啊 啊啊啊 覺得自己好慘吶 只好自我安慰了 這個(gè)女孩子...
    葉慢慢05閱讀 187評(píng)論 0 0