最近有感而發(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前慷垮,我們先說一波一些概念:
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)欄的顏色北戏。