從頭寫一個項目---ToolBar的封裝處理

最近有感而發(fā)宣肚,突然想著建立一個項目的基礎(chǔ)庫,收集一些項目中常見的問題俭令,并且作為一個獨立的基礎(chǔ)Lib漆魔。今天我們封裝ToolBar來進(jìn)行開發(fā),ToolBar是一個高度可獨立定制的標(biāo)題欄,每個項目都必不可少农猬。

源碼地址

使用前的準(zhǔn)備

首先赡艰、我們需要用到ToolBar,高版本Activity必須繼承AppCompatActivity,以前還有一個ActionBarActivity.

其次斤葱、app要繼承無ActionBar的主題如下:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
     <item name="colorAccent">@color/colorAccent</item>

 </style></pre>

開始說Api前慷垮,我們先說一波一些概念:

image

1.是導(dǎo)航按鈕:其對應(yīng)的id是 android.R.id.home。揍堕,可以自定義事件料身,也可以用數(shù)據(jù)元導(dǎo)航。

2.Logo:就是一個圖標(biāo)衩茸,沒有事件處理芹血。

3.是Title,就是我們常見的標(biāo)題楞慈。

4.我理解為右邊的可拓展區(qū)域幔烛,這塊地方一般我不會封裝。都是根據(jù)Activity不同設(shè)置不同抖部。

ToolBar的一些簡答的Api說明

activity.setSupportActionBar(mToolbar):設(shè)置可供使用的ToolBar對象说贝,替換Actionbar。

activity.getSupportActionBar():獲取到替換后的ActionBar對象慎颗,然后可以對這個actionBar進(jìn)行操作乡恕。

以下是v7包ActionBar的API:

getSupportActionBar().setLogo(resId):設(shè)置Logo圖標(biāo)。

getSupportActionBar().setTitle(String):設(shè)置標(biāo)題俯萎。

getSupportActionBar().setDisplayShowTitleEnabled(Boolean):設(shè)置導(dǎo)航按鈕是否可見傲宜。

getSupportActionBar().setDisplayUseLogoEnabled(Boolean):設(shè)置Logo是否可見。

getSupportActionBar().setDisplayShowTitleEnabled(Boolean):設(shè)置標(biāo)題是否可見夫啊。

     getSupportActionBar().setBackgroundDrawable(colorDrawable):設(shè)置背景顏色函卒。

開始使用ToolBar

簡單的使用

<android.support.v7.widget.Toolbar
     android:id="@+id/toolbar"
    android:layout_width="match_parent"
     android:layout_height="?actionBarSize"
     android:background="@color/colorPrimary"
     app:theme="@style/ToolbarTheme"
     app:logo="@mipmap/back"
    android:fitsSystemWindows="true"
     app:popupTheme="@style/ToolbarPopupTheme"
     app:titleTextAppearance="@style/ToolBar.TitleText"
     android:minHeight="?actionBarSize">

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

?actionBarSize:獲取到系統(tǒng)actionBar的高度設(shè)置。

android:background="@color/colorPrimary":設(shè)置背景顏色撇眯。

app:theme="@style/ToolbarTheme":標(biāo)題欄的樣式报嵌。

app:popupTheme="@style/ToolbarPopupTheme":點擊右邊出現(xiàn)浮動菜單的樣式虱咧。

app:titleTextAppearance="@style/ToolBar.TitleText":Title 的樣式。

 private void initToolBar() {
    mToolbar =findViewById(R.id.toolbar);
     setSupportActionBar(mToolbar);>         if (getSupportActionBar()!=null){
       //默認(rèn)為null
         getSupportActionBar().setLogo(null);
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(true);
     }
}

從Xml中獲取到ToolBar然后替換掉系統(tǒng)的ActionBar,我們就可以對其進(jìn)行默認(rèn)的操作锚国,Title默認(rèn)為項目名稱腕巡。

自定制View嵌入

雖然ToolBar大部分情況還是能滿足我們對標(biāo)題欄的要求,但是由于業(yè)務(wù)的復(fù)雜性血筑,我們有時候還是不得不對ToolBar再進(jìn)行定制绘沉。

但是定制也是很簡單的,比如xml我們這樣寫:

 <android.support.v7.widget.Toolbar
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="?actionBarSize"
     android:background="@color/colorPrimary"
     app:theme="@style/ToolbarTheme"
     app:logo="@mipmap/back"
     android:fitsSystemWindows="true"
     app:popupTheme="@style/ToolbarPopupTheme"
    app:titleTextAppearance="@style/ToolBar.TitleText"
   android:minHeight="?actionBarSize">

     <LinearLayout
         android:layout_gravity="center_horizontal"
         android:layout_width="200dp"
         android:layout_height="wrap_content"
        android:orientation="horizontal">

         <Button
             android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="按鈕一"/>
         <Button
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:text="按鈕一"/>
         <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="按鈕一"/>

    </LinearLayout>

   <TextView
         android:layout_gravity="end|center_vertical"
        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginRight="@dimen/dp_value_10"
         android:layout_marginEnd="@dimen/dp_value_10"
         android:textColor="@android:color/white"
         android:text="我在右邊"/>

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

其實就是在ToolBar容器中豺总,添加View, 然后通過 android:layout_gravity標(biāo)簽對控件進(jìn)行排列车伞,ToolBar是一個類似LinearLayout的容器。而且原有的配置是可以和自定制的進(jìn)行互用的喻喳。

然后就是通過findById進(jìn)行設(shè)置了另玖,很普通的操作我就不寫了。

源代碼見:BaseApp項目

Sample主項目中的:ActionBarActivity

右邊菜單的擴展

app:showAsAction講解:

always:使菜單項一直顯示在ToolBar上表伦。

ifRoom:如果有足夠的空間日矫,這個值會使菜單項顯示在ToolBar上。

never:使菜單項永遠(yuǎn)都不出現(xiàn)在ToolBar上,在…的子項中顯示绑榴。

withText:withText值示意Action bar要顯示文本標(biāo)題。Action bar會盡可能的顯示這個
標(biāo)題盈魁,但是如果圖標(biāo)有效或者文本太長翔怎,會導(dǎo)致不能顯示或者顯示不全的情況。

collapseActionView :聲明了這個操作視窗應(yīng)該被折疊到一個按鈕中杨耙,當(dāng)用戶選擇這個按鈕時赤套,這個操作視窗展開。否則珊膜,
這個操作視窗在默認(rèn)的情況下是可見的容握,并且即便在用于不適用的時候,也要占據(jù)操作欄的有效空間车柠。
一般要配合ifRoom一起使用才會有效果剔氏。

寫一個menu.xml 菜單xml

<?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/action_search"
    android:title="搜索"
    android:icon="@mipmap/search"
    app:showAsAction="always"
    app:actionViewClass="android.support.v7.widget.SearchView" />
<item
    android:id="@+id/action_setting"
    android:title="設(shè)置"
    app:showAsAction="never"
    />
<item
    android:id="@+id/action_show"
    android:title="顯示"
    android:icon="@mipmap/search"
    app:showAsAction="withText"
    />
<item
    android:id="@+id/action_hide"
    android:title="隱藏"
    app:showAsAction="never"
    />
</menu>

對菜單進(jìn)行擴展:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_right,menu);
    return true;
}

對菜單的事件進(jìn)行定義:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId())
    {
        case R.id.action_search:
            Toast.makeText(MainActivity.this, "搜索", Toast.LENGTH_SHORT).show();
            break;
        case R.id.action_setting:
            Toast.makeText(MainActivity.this, "設(shè)置", Toast.LENGTH_SHORT).show();
            break;
        case R.id.action_show:
            Toast.makeText(MainActivity.this, "顯示", Toast.LENGTH_SHORT).show();
            break;
        case R.id.action_hide:
            Toast.makeText(MainActivity.this, "隱藏", Toast.LENGTH_SHORT).show();
            break;
    }

    return super.onOptionsItemSelected(item);
}</pre>

導(dǎo)航按鈕的點擊事件處理

導(dǎo)航按鈕有三次種處理事件的方式

方法一:在AndroidManifest.xml中設(shè)置元數(shù)據(jù)。比如:我們需要點擊后跳轉(zhuǎn)到MainActivity:

<activity android:name=".ui.ActionBarActivity">
        <meta-data android:name="android.support.PARENT_ACTIVITY"
            android:value=".ui.MainActivity"/>
    </activity></pre>

設(shè)置了父Activity后竹祷,點擊直接跳轉(zhuǎn)到父Activity.

方法二:通過導(dǎo)航按鈕的id android.R.id.home 判斷處理事件:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()==android.R.id.home){
       if (NavUtils.getParentActivityName(this)!=null){
           NavUtils.navigateUpFromSameTask(this);
       }else {
           finish();
       }
    }
    return super.onOptionsItemSelected(item);
}</pre>

方式三:使用ToolBar對象設(shè)置監(jiān)聽事件:

getToolbar().setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(MainActivity.this, "點擊了導(dǎo)航按鈕", Toast.LENGTH_SHORT).show();
        }
    });</pre>

其實方式三就是方式二的原理谈跛,我們看看下面的源碼,這是從ToolbarWidgetWrapper扒出來的:

 mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
                0, android.R.id.home, 0, 0, mTitle);
        @Override
        public void onClick(View v) {
            if (mWindowCallback != null && mMenuPrepared) {
                mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mNavItem);
            }
        }
    });

從上面的源碼可以看到塑陵,其實就是通過點擊事件感憾,再次調(diào)用窗口的菜單選擇回調(diào),所以方式三優(yōu)先級比方式二更高令花。

SearchView的使用

使用SearchView我們需要設(shè)置

app:actionViewClass="android.support.v7.widget.SearchView"</pre>

然后 可以在onCreateOptionsMenu方法中獲取到SearchView阻桅,用SearchManager 和SearchView進(jìn)行綁定

  @Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_right,menu);

    MenuItem serachTtem=menu.findItem(R.id.action_search);
    SearchView searchView= (SearchView) serachTtem.getActionView();

    SearchManager searchManager= (SearchManager) getSystemService(Context.SEARCH_SERVICE);
   if (searchManager!=null){
       searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
   }

    return true;
}</pre>

這樣設(shè)置鍵盤右下角會變成確認(rèn)搜索按鈕凉倚,點擊會進(jìn)行搜索,下一步進(jìn)行接受源的設(shè)置

<activity android:name=".ui.MainActivity"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            android:name="android.app.default_searchable"
            android:value=".ui.SearchResultActivity" />
    </activity></pre>

meta-data元數(shù)據(jù)定義了value就是接收 搜索框輸入的內(nèi)容的Activity. 也可以是MainActivity本身:

接收數(shù)據(jù)的Activity還需要設(shè)置如下數(shù)據(jù)元 searchable.xml:

<?xml version="1.0" encoding="utf-8"?>
  <searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:imeOptions="actionSearch"
android:hint="姓名" /></pre>

<activity android:name=".ui.SearchResultActivity">
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
    </activity></pre>

配置好我們還需要獲取到輸入的內(nèi)容進(jìn)行搜索:

String SearchContent = getIntent().getStringExtra(SearchManager.QUERY);

然后就可以拿這段內(nèi)容去網(wǎng)絡(luò)查詢了嫂沉。

源代碼見:BaseApp項目

Sample主項目中的:MainActivity

標(biāo)題欄的樣式

<!-- ToolBar菜單樣式 -->
<style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
    <item name="colorControlNormal">@android:color/white</item><!--  導(dǎo)航按鈕是顏色 -->
    <item name="actionMenuTextColor">@android:color/white</item> <!--  標(biāo)題欄菜單顏色-->
    <item name="selectableItemBackground">@drawable/toolbar_select_menu_bg</item><!--  選擇菜單的背景顏色-->
    <item name="searchViewStyle">@style/ToolBar.Widget.SearchView</item><!--  搜索框樣式-->
    <item name="android:textColorHint">@android:color/white</item><!--  搜索框提示字體顏色-->
    <item name="android:textColorPrimary">@android:color/black</item><!--  搜索框輸入字體顏色-->
    <item name="android:textCursorDrawable">@drawable/color_cursor</item><!--  搜索框光標(biāo)顏色-->
</style>

<!--  TitleText-->
<style name="ToolBar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <item name="android:textColor">@android:color/white</item><!--  Title 的字體顏色-->
</style>

<!--  菜單的樣式-->
<style name="ToolbarPopupTheme" parent="@style/ThemeOverlay.AppCompat">
    <item name="android:colorBackground">@color/colorPrimaryDark</item><!--  菜單的背景顏色-->
    <item name="android:textColor">@android:color/white</item><!--  菜單的字體顏色-->

</style>

<!--  搜索框的樣式-->
<style name="ToolBar.Widget.SearchView" parent="Base.Widget.AppCompat.SearchView">
    <item name="defaultQueryHint">請輸入關(guān)鍵字</item><!--  搜索框提醒Hint-->
</style></pre>

詳情請查看源碼稽寒。

封裝后AbstractActivity API使用說明

學(xué)習(xí)了ToolBar之后對ToolBar進(jìn)行了一定的封裝,實現(xiàn)了一些常見的功能输瓜,繼承AbstractActivity可用:

setSupportActionBarTitle(String title):設(shè)置ActionBar的標(biāo)題瓦胎。

setSupportActionBarLogo(Integer resId):設(shè)置Logo.

setCustomToolBar(View view):設(shè)置一個自定義布局。

setSupportActionBarBackgroundDrawable(@ColorRes int color):設(shè)置一個背景顏色尤揣。

setDisplayHomeAsUpEnabled(boolean show):設(shè)置是否顯示導(dǎo)航按鈕搔啊。

setDisplayShowTitleEnabled(boolean show:設(shè)置是否顯示標(biāo)題。

setDisplayUseLogoEnabled(boolean show):設(shè)置是否顯示Logo.

setStatusBarColor(@ColorRes int color):修改狀態(tài)欄的顏色北戏。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末负芋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嗜愈,更是在濱河造成了極大的恐慌旧蛾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蠕嫁,死亡現(xiàn)場離奇詭異锨天,居然都是意外死亡,警方通過查閱死者的電腦和手機剃毒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門病袄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赘阀,你說我怎么就攤上這事益缠。” “怎么了基公?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵幅慌,是天一觀的道長。 經(jīng)常有香客問我轰豆,道長胰伍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任酸休,我火速辦了婚禮喇辽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雨席。我一直安慰自己菩咨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抽米,像睡著了一般特占。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上云茸,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天是目,我揣著相機與錄音,去河邊找鬼标捺。 笑死懊纳,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亡容。 我是一名探鬼主播嗤疯,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闺兢!你這毒婦竟也來了茂缚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤屋谭,失蹤者是張志新(化名)和其女友劉穎脚囊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桐磁,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡悔耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了我擂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淮逊。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖扶踊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郎任,我是刑警寧澤秧耗,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站舶治,受9級特大地震影響分井,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜霉猛,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一尺锚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惜浅,春花似錦瘫辩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽承绸。三九已至,卻和暖如春挣轨,著一層夾襖步出監(jiān)牢的瞬間军熏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工卷扮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留荡澎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓晤锹,卻偏偏與公主長得像摩幔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抖甘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

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