在開(kāi)發(fā)的過(guò)程中經(jīng)常要用到工具欄和菜單欄,有時(shí)候你看到有些APP的工具欄多么炫酷,然你也想做一個(gè)類(lèi)似的,發(fā)現(xiàn)在做的過(guò)程中會(huì)遇到許多的坑,至于那些坑只有你自己去通過(guò)編碼、調(diào)試、發(fā)現(xiàn)問(wèn)題、查閱資料、解決問(wèn)題一般開(kāi)發(fā)都需要經(jīng)過(guò)這個(gè)過(guò)程。所以在此將此知識(shí)點(diǎn)通過(guò)博客的形式記錄下來(lái)。
- 工具欄文字樣式設(shè)置:
居中
、顏色
、大小
等屬性設(shè)置
- 設(shè)置工具欄的
Style
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/view_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:minHeight="?attr/actionBarSize">
<TextView
android:id="@+id/tv_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorAccent"
android:layout_gravity="center"
android:text="Toolbar Title"/>
</android.support.v7.widget.Toolbar>
需要注意的幾點(diǎn)是:
-
Toolbar
可以通過(guò)android:background
設(shè)置背景色。 -
Toolbar
可以通過(guò)layout_height
設(shè)置工具欄的高度,上面是設(shè)置為系統(tǒng)AcitonBar
默認(rèn)大小,我個(gè)人習(xí)慣設(shè)置為50dp。 - 工具欄的各種屬性可以通過(guò)設(shè)置
TextView
的屬性來(lái)展現(xiàn)到UI
,layout_gravity
屬性相對(duì)于父布局也就是這里的Toolbar
來(lái)說(shuō)的,而gravity
屬性是相對(duì)于自己控件本身的布局。
- 代碼設(shè)置工具欄的標(biāo)題等屬性
tvToolbar.setText(title);//set toolbar textView content
- 如何隱藏系統(tǒng)自帶的工具欄?
- 通過(guò)配置XML實(shí)現(xiàn)
- 設(shè)置界面全屏效果
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- 設(shè)置無(wú)標(biāo)題
android:theme="@android:style/Theme.NoTitleBar"
本Demo是統(tǒng)一設(shè)置所有頁(yè)面為無(wú)標(biāo)題,通過(guò)設(shè)置Style
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
然后添加到AndroidManifest.xml
的App的theme
屬性中
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
- 通過(guò)代碼實(shí)現(xiàn)
- 設(shè)置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- 設(shè)置無(wú)標(biāo)題欄
requestWindowFeature(Window.FEATURE_NO_TITLE);
注意:這些都是設(shè)置代碼需要寫(xiě)在調(diào)用設(shè)置布局文件之前
- 如何在工具欄上優(yōu)雅地使用菜單欄(SearchView)
- 工具欄配置文件XML
<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:icon="@android:drawable/ic_menu_search"
android:title="@android:string/search_go"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom"/>
</menu>
*注意:這里一定要設(shè)置app:actionViewClass="android.support.v7.widget.SearchView"
不然實(shí)例化獲取到的對(duì)象為null
,app:showAsAction
設(shè)置有collapseActionView
屬性,searchView菜單欄才會(huì)有返回箭頭
- 使用工具欄的配置文件XML
<include layout="@layout/view_toolbar"/>
- 加載工具欄的
Menu
//toolbar add menu
toolbar.inflateMenu(R.menu.menu_search);
toolbar.setOnMenuItemClickListener(onMenuItemClickListener);
//toolbar search menu click listener
private Toolbar.OnMenuItemClickListener onMenuItemClickListener = new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//charge the id is equal what you want
if (item.getItemId() == R.id.action_search) {
queryData(item);
}
return false;
}
};
- 不使用系統(tǒng)菜單欄會(huì)導(dǎo)致一些菜單欄相關(guān)函數(shù)
Override
的onPrepareOptionsMenu
、onOptionsItemSelected
等函數(shù)不調(diào)用如何解決?
- 基于
Fragment
頁(yè)面
在onCreate
設(shè)置setHasOptionsMenu(true)
和onViewCreated
設(shè)置getActivity().invalidateOptionsMenu()
但是我測(cè)試發(fā)現(xiàn)并沒(méi)有沒(méi)有調(diào)用onPrepareOptionsMenu
等函數(shù),這個(gè)后續(xù)查閱資料stackOverFlow這個(gè)好像沒(méi)有解決此問(wèn)題 - 基于
Activity
頁(yè)面
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
也可以像設(shè)置前面設(shè)置APP所有頁(yè)面無(wú)標(biāo)題一樣設(shè)置Activity
<!-- Activity theme. -->
<style name="ActivityTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
然后設(shè)置到AndroidManifest.xml
的指定的Activity的theme
屬性中
<activity
android:name=".SearchViewActivity"
android:theme="@style/ActivityTheme">
</activity>
- 使用SearchView過(guò)程中你需要注意的問(wèn)題和一個(gè)常見(jiàn)的BackPress退出問(wèn)題
- 開(kāi)啟系統(tǒng)搜索服務(wù)
SearchManager manager = (SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE);
- 實(shí)例化SearchView對(duì)象
mSearchView = (SearchView) item.getActionView();
- 設(shè)置
setOnQueryTextListener
事件監(jiān)聽(tīng)搜索條件
//on query text listener
private SearchView.OnQueryTextListener onQueryTextListener = new SearchView.OnQueryTextListener() {
@Override //submit the search condition
public boolean onQueryTextSubmit(String query) {
Toast.makeText(getContext(), "Search Data in fragment", Toast.LENGTH_SHORT).show();
return false;
}
@Override //the search condition once changed will invoke this funtion
public boolean onQueryTextChange(String newText) {
return false;
}
};
- 設(shè)置
setOnQueryTextFocusChangeListener
事件監(jiān)聽(tīng)輸入框焦點(diǎn)的變化通過(guò)此函數(shù)解決了OnBackPressed
直接退出APP的問(wèn)題
//the focus of the query condition box once changed , will call this funtion
mSearchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean focused) {
//charge the focus is changed and the searchview icon isn't iconified
if (!focused && !mSearchView.isIconified()) {
//in the fragment you mus you this way can solve it
MenuItemCompat.collapseActionView(item);
}
}
});
- 網(wǎng)上說(shuō)的關(guān)閉活動(dòng)的SearchView時(shí)的解決辦法是
override
onBackPressed
函數(shù)
@Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}
在Fragment中當(dāng)然沒(méi)有這個(gè)函數(shù)可以讓你重寫(xiě),但是可以通過(guò)在基類(lèi)implement OnBackPressed(自己定義的)
接口詳情請(qǐng)見(jiàn)onBackPressed() for Fragments,我通過(guò)此方法,使用上面的這種發(fā)現(xiàn)效果圖如before.gif
并不是解決辦法,還是監(jiān)聽(tīng)setOnQueryTextFocusChangeListener
是正確的,正確圖片如下perfect.gif
- 關(guān)于Toolbar使用的一些思考和總結(jié)
- 網(wǎng)絡(luò)上此類(lèi)型的提問(wèn)太多,回答也太多,至于真正正確的答案需要你自己動(dòng)手編碼,自己經(jīng)過(guò)測(cè)試才知道。
- Toolbar是受到系統(tǒng)樣式的約束,如果自己設(shè)置了NoActionBar ,FullScreen等樣式的話(huà)就會(huì)沒(méi)有工具欄。
- 你使用系統(tǒng)默認(rèn)的樣式
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
,然后在每個(gè)頁(yè)面有自己定義的toolbar的話(huà),這樣會(huì)導(dǎo)致有兩個(gè)工具欄[自己可以測(cè)試]。 - 題外簡(jiǎn)書(shū)如何生成目錄,網(wǎng)絡(luò)上找的在后面添加
[toc]
貌似沒(méi)用。
- 參考鏈接
Implementing SearchView in action bar
Android toolbar center title and custom font
How do I close a SearchView programmatically?
onPrepareOptionsMenu not getting called in Fragments
-
完整源碼傳送門(mén)
CenterTooolBarText:https://github.com/GitACDreamer/CenterToolbarText