ToolBar隨心定制

臨近年末猪钮,項目沒什么新需求了好爬,主要做一些code review和代碼重構(gòu)的工作即彪。有一個工作是將我們app中的TitleBar替換為Android的原生控件ToolBar味抖,ToolBar出來這么久评甜,相信大家都不會陌生了。替換的工作并不難非竿,但因為我們App原來的TitleBar是一個相對布局中間放了一些ImageButton和TextView等控件組成的蜕着,并不符合ToolBar的原生風格,所以我一開始打算放棄替換红柱,但經(jīng)過一番Google,發(fā)現(xiàn)原來還是可以輕松實現(xiàn)的蓖乘,不得不感嘆ToolBar的定制性真得很強锤悄。

我需要替換的TitleBar樣式
原生風格的ToolBar

關(guān)于ToolBar的基本用法網(wǎng)上一大堆,不會的童鞋可以自己去Google嘉抒,我這里簡單總結(jié)一下如何更自由的定制ToolBar零聚。

一. Title居中

ToolBar默認的主Title是居左的,但是我們可以通過自定義ToolBar的子View來達到顯示居中Title的效果。

<android.support.v7.widget.Toolbar
    android:id="@+id/toolBar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="自定義標題"
        android:textColor="@color/black"
        android:textSize="@dimen/title_center_textsize" />

</android.support.v7.widget.Toolbar>

這樣還可以單獨控制中間標題的字體顏色和大小等隶症。使用TextView作為title后政模,toolbar.setTitle(...)就可以設(shè)置為空或者不用設(shè)置了。

二. 在ToolBar左側(cè)放置Menu

在ToolBar添加Menu時蚂会,默認都是出現(xiàn)在右側(cè)的淋样,但我的需求是在左側(cè)放置兩個Menu,本來想通過設(shè)置NavigationIcon和logo來解決胁住,但如果這樣趁猴,只能設(shè)置兩個圖標在左邊,而且圖標之間的間距沒辦法調(diào)整彪见,所以靈活性很差儡司。后來發(fā)現(xiàn)一個非常好用的控件ActionMenuView,以前它可以搭配ActionBar來使用余指,現(xiàn)在同樣可以用來自定義ToolBar的菜單捕犬。

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/title_height"
        android:background="@color/title_background"
        android:minHeight="@dimen/title_height"
        app:contentInsetLeft="0dp"
        app:contentInsetStart="0dp"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

        <android.support.v7.widget.ActionMenuView
            android:id="@+id/action_menu_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/toolbar_title"
            style="@style/TitleBar.Text.Center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />


    </android.support.v7.widget.Toolbar>

將ActionMenuView放在ToolBar子布局中的第一個,它就會繪制在左側(cè)酵镜,還需要注意給ToolBar設(shè)置下面的屬性(而且需要注意碉碉,這里要使用"app:xxx"而不是"Android:xxx",否則會有兼容性問題)笋婿,因為當沒有設(shè)置NavigationIcon和logo時誉裆,ToolBar左側(cè)默認有一小段空白:

app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"

然后我們需要給ActionMenuView加載菜單,代碼很簡單:

ActionMenuView actionMenuView = (ActionMenuView) toolbar.findViewById(R.id.action_menu_view);
getMenuInflater().inflate(R.menu.menu_toolbar_left, actionMenuView.getMenu());
// 點擊事件
actionMenuView.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        return false;
    }
});

R.menu.menu_toolbar_left.xml文件就是放置在menu文件夾下我們自定義的菜單資源文件缸濒。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/left_back_btn"
        android:icon="@drawable/ic_titlebar_back"
        android:title="后退"
        app:showAsAction="always"/>

    <item
        android:id="@+id/left_text_btn"
        android:title=""
        app:actionLayout="@layout/menu_layout_text_btn"
        app:showAsAction="always"/>

    <item
        android:id="@+id/left_icon_btn"
        android:icon="@drawable/ic_launcher"
        android:title=""
        app:showAsAction="always"/>

</menu>
左邊菜單顯示效果

細心的同學應(yīng)該看到我第二個id為left_text_btn的菜單使用了app:actionLayout屬性足丢,這是使當前菜單顯示你指定的layout布局,也是非常方便的定制功能庇配。因為ToolBar中所有菜單的顏色必須統(tǒng)一指定(通過在AppTheme中指定"android:actionMenuTextColor"屬性)斩跌,沒辦法分開設(shè)置,所以如果需要單獨設(shè)置某個菜單的顏色捞慌,可以指定它的app:actionLayout耀鸦,上面的"@layout/menu_layout_text_btn"布局為一個簡單的TextView,就不貼了啸澡,也可以通過代碼指定:

MenuItem menuItem = actionMenuView.getMenu().findItem(R.id.left_text_btn);
menuItem.setActionView(R.layout.menu_layout_text_btn);

還有一個細節(jié)可能也有人關(guān)注到袖订,就是如果菜單按鈕是通過icon屬性設(shè)置的圖標按鈕,長按就會出現(xiàn)Toast文字(title屬性設(shè)置的文字)提示這個圖標按鈕的作用嗅虏,即便title設(shè)為空字符串洛姑,也還是會彈出Toast,這是Android系統(tǒng)的默認設(shè)置皮服,無法取消楞艾,如果實在不想要這個提示参咙,可以通過指定其app:actionLayout為一個自定義的ImageButton來實現(xiàn)。注意當使用app:actionLayout屬性定制菜單時硫眯,點擊事件就需要通過設(shè)置app:actionLayout指定的layout中的View的Click監(jiān)聽來實現(xiàn)了

// 此時menuItem.getActionView()獲取的View就是自定義的ImageButton或TextView
menuItem.getActionView().setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        
    }
});

默認的MenuItem點擊效果為一個小圓形的水波紋效果蕴侧,查看自帶style是通過下面的資源文件實現(xiàn)的,自定義時可以指定為它以保持點擊效果一致:

android:background="?attr/actionBarItemBackground"

三. Menu的間距和文字屬性設(shè)置

有時我們需要設(shè)置按鈕文字的顏色以及大小两入,還需要調(diào)整相鄰按鈕之間的間距净宵,比如上圖中可能有人會覺得"<"后退按鈕和“關(guān)閉”按鈕之間的間距太大了,這要如何調(diào)整呢谆刨?都可以通過指定Theme中的屬性來設(shè)置塘娶。

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:actionMenuTextColor">@color/primary</item>
        <item name="android:actionMenuTextAppearance">@style/ActionMenuTextAppearance</item>
        <item name="android:actionButtonStyle">@style/ActionButtonStyle</item>
    </style>

android:actionMenuTextColor屬性用來指定菜單文字的顏色,android:actionMenuTextAppearance是用來指定菜單文字的大小等屬性

    <style name="ActionMenuTextAppearance" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Menu">
        <item name="android:textSize">@dimen/title_right_textsize</item>
        <item name="android:textStyle">normal</item>
    </style>

android:actionButtonStyle可以修改按鈕的大小和間距

    <style name="ActionButtonStyle" parent="Widget.AppCompat.Light.ActionButton">
        <item name="android:minWidth">44dp</item>
        <item name="android:paddingLeft">10dp</item>
        <item name="android:paddingRight">10dp</item>
    </style>

這里因為api17以下使用的是paddingLeft和paddingRight痊夭,而api17以上使用的是paddingStart和paddingEnd(通過查看Widget.AppCompat.Light.ActionButton的style源碼也可以看到)刁岸,所以這里需要新建values-v17文件夾,在其下新建styles.xml來專門指定api17以上的ActionButtonStyle:

    <style name="ActionButtonStyle" parent="Widget.AppCompat.Light.ActionButton">
        <item name="android:minWidth">44dp</item>
        <item name="android:paddingStart">10dp</item>
        <item name="android:paddingEnd">10dp</item>
    </style>

ActionButton默認的android:minWidth屬性值為48dp她我,默認左右的padding值為12dp虹曙。


ActionButton默認的android:minWidth屬性值

所以如果我們需要修改按鈕的間距,可以修改以上三個屬性值番舆,改小之后可以明顯看到間距減小


minWidth改為20dp酝碳,左右padding改為0dp的效果

四. 總結(jié)

以上就是這次替換的一小點經(jīng)驗總結(jié),右邊的菜單通過直接給ToolBar添加Menu就可以了恨狈,當然你也可以通過自定義的方式實現(xiàn)疏哗。通過以上幾點,我們可以看到ToolBar的非常靈活的可定制性禾怠,不僅如此返奉,如果你的菜單還有更不一樣的地方,可以把ToolBar中的內(nèi)容全部通過自定義布局來實現(xiàn)吗氏,也就是全部通過ToolBar的子View們來展示ToolBar的內(nèi)容芽偏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弦讽,隨后出現(xiàn)的幾起案子污尉,更是在濱河造成了極大的恐慌,老刑警劉巖往产,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件被碗,死亡現(xiàn)場離奇詭異,居然都是意外死亡仿村,警方通過查閱死者的電腦和手機蛮放,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奠宜,“玉大人包颁,你說我怎么就攤上這事⊙拐妫” “怎么了娩嚼?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滴肿。 經(jīng)常有香客問我岳悟,道長,這世上最難降的妖魔是什么泼差? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任贵少,我火速辦了婚禮,結(jié)果婚禮上堆缘,老公的妹妹穿的比我還像新娘滔灶。我一直安慰自己,他們只是感情好吼肥,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布录平。 她就那樣靜靜地躺著,像睡著了一般缀皱。 火紅的嫁衣襯著肌膚如雪斗这。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天啤斗,我揣著相機與錄音表箭,去河邊找鬼。 笑死钮莲,一個胖子當著我的面吹牛免钻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臂痕,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼伯襟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了握童?” 一聲冷哼從身側(cè)響起姆怪,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澡绩,沒想到半個月后稽揭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡肥卡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年溪掀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片步鉴。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡揪胃,死狀恐怖璃哟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喊递,我是刑警寧澤随闪,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站骚勘,受9級特大地震影響铐伴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俏讹,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一当宴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泽疆,春花似錦户矢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至株依,卻和暖如春驱证,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恋腕。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工抹锄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荠藤。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓伙单,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哈肖。 傳聞我的和親對象是個殘疾皇子吻育,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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