今天咱們來聊一聊有關AppCompat,做爲Android Jetpack系列文章的開篇。說到Android Jetpack,咱們先看一下這張圖:
從圖中咱們能夠看到,整個Android Jetpack分爲了四大部分,而咱們今天要講述的就是Foundation中的AppCompat小節,官方將該部分翻譯爲「基礎」。
Google官方網站:
https://developer.android.com/jetpack
按照Google官方的描述,AppCompat就是指v7 appcompat庫。android
「This library adds support for the Action Bar user interface design pattern. This library includes support for material design user interface implementations.」git
意思是:此庫添加了對操做欄用戶界面設計模式的支持。這個庫包括對Material Design用戶界面實現的支持。也就是說,咱們能夠藉助該庫,對Material Design有更便捷和兼容性更好的實現。
進入AppCompat章節後,咱們發現它又被分爲了4個部分,這4個部分被稱爲「key class」,也就是重點類,它們分別是:github
想要使用這些類,咱們須要添加v7支持庫。
到如今爲止,支持庫的最新版本是28,添加的庫名稱和版本以下:設計模式
com.android.support:appcompat-v7:28.0.0
今天咱們就先來聊一聊ActionBar,也是這裏面最爲複雜的一個部分。
依稀記得,伴隨着Google I/O 2014的召開,早在Android 5.0的時代,Google 官方推出了ToolBar組件,在那以後,ToolBar就登上了歷史舞臺,扮演着重要的角色。以前我在CSDN上面也發表過相關主題的文章,由於發佈的時機恰好是ToolBar登場之際,因此得到了不少的閱讀量。快5年過去了,回頭再看那幾篇連載,感受文筆非常稚嫩。今天藉着講述Jetpack,再次聊聊ToolBar那些事,相信你我都會有新的收穫。app
首先解決疑問:ide
問:既然有了ActionBar,爲什麼還要用ToolBar? 答:使用AppCompat Toolbar能兼容更普遍的設備(ActionBar要求最低Android 3.0,ToolBar要求最低Android 2.1,但只有Android 5.0及以上才能在不使用AppCompat兼容包的前提下支持Material Design),以及各式各樣的自定義需求。佈局
問:ToolBar上面都應該包含哪些內容? 答:根據Google的指導,應用欄區域應具有如下要素:1)一個專用區域,能夠標識您的應用並指示用戶在應用中的位置;2)以可預測的方式訪問搜索等重要操做;3)支持導航和視圖切換(經過標籤頁或下拉列表)。網站
1、添加ToolBar
想要添加一個ToolBar,總共3步走:
1. 更改application主題樣式,操做對象:styles.xml。
對於新建的Android項目,AndroidManifest.xml中已經定義了所使用的theme,即:this
android:theme="@style/AppTheme"
此時,咱們修改styles.xml文件便可,將默認的繼承值改掉,以下所示:google
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
2. 在Activity佈局中添加ToolBar,操做對象:layout佈局文件
<android.support.v7.widget.Toolbar android:id="@+id/activity_main_tb" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
對高度掌握很差火候的同窗,直接如上使用ActionBar的高度就能夠了。
android:evevation指「仰角」,這部分知識請參考:
https://developer.android.com/training/material/shadows-clipping
這裏就再也不贅述了。
若是你的項目已經遷移到Android X,你的佈局文件代碼片應該是:
<androidx.appcompat.widget.Toolbar android:id="@+id/activity_main_tb" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
3. 在Activity類中找到ToolBar,並應用它,操做對象:Activity類
這一步並不複雜,參考普通的Android控件。相似地,咱們經過findViewById()找到ToolBar,並作執行一些設定,便可完成該步驟,示例以下:
private Toolbar topTb; topTb = findViewById(R.id.activity_main_tb); setSupportActionBar(topTb);
一旦咱們setSupportActionBar()後,往後咱們就能夠經過getSupportActionBar()方法來獲取ToolBar實例,也可使用兼容包提供的ActionBar的各類API方法了。
到此,咱們就完成了ToolBar的添加,還算簡單吧?
2、ToolBar外觀的自定義
不出意外的話,咱們運行的結果將會和下圖相似:
大綠底,大黑字,實在不怎麼好看。
那麼,若是咱們想要自定義配色方案,該如何作呢?參考下圖:
這些值咱們均可以在color.xml中定義,並在styles.xml中引用。下圖是一個從新定義配色方案後的截圖:
相關的代碼片:
color.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#002FA7</color> <color name="colorPrimaryDark">#001F67</color> <color name="colorAccent">#003FB7</color> <color name="textColorPrimary">#FFFFFF</color> </resources>
styles.xml
<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> <item name="android:textColorPrimary">@color/textColorPrimary</item> </style>
細心的讀者會發現,後面的截圖中,右上角多了菜單項,這又是如何實現的呢?咱們繼續日後看。
3、給ToolBar增長動做
首先咱們來看看如何給ToolBar增長菜單,咱們依然分爲3步完成。
1. 編寫菜單xml文件,操做對象:menu文件夾下的菜單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/menu_main_info" android:title="@string/menu_main_activity_info" app:showAsAction="never" /> <item android:id="@+id/menu_main_search" android:title="@string/menu_main_activity_search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always" /> </menu>
如上,咱們能夠看到有兩個item,分別對應Info和搜索,咱們使用"app:showAsAction"的值來控制這個菜單是否顯示,常見的值有always,ifRoom,never。從字面上也很好理解,這裏就很少解釋了。
2. 接下來是Java代碼片斷:
private SearchView tbSearchSv; @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_activity_menu, menu); MenuItem searchItem = menu.findItem(R.id.menu_main_search); tbSearchSv = (SearchView) searchItem.getActionView(); return super.onCreateOptionsMenu(menu); }
細心的朋友會發現有這一行:
app:actionViewClass="android.support.v7.widget.SearchView"
它是作什麼的呢?
對了!它就是搜索欄,是原生的搜索欄。因此某些狀況下,這個搜索欄是不用本身去實現的,系統已經給咱們提供了SearchView!
典型的APP:網易雲音樂、知乎上方的搜索都是這樣的。
3. 爲菜單設置監聽器,咱們先來看最普通的Info按鈕,咱們只需在Java代碼中Override指定的方法就能夠了,以下所示:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_main_info: Toast.makeText(MainActivity.this, R.string.menu_main_activity_info, Toast.LENGTH_LONG).show(); break; } return super.onOptionsItemSelected(item); }
對於搜索欄,首先咱們想到的是,如何獲取用戶輸入的內容呢?
其實很簡單,玄機在於SearchView,只需對SearchView添加監聽器就能夠了。
tbSearchSv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { return false; } @Override public boolean onQueryTextChange(String s) { return false; } });
這裏要注意,設置監聽器前,要確保SearchView(這裏的tbSearchSv)已經被實例化,不然,會出現空指針異常崩潰。
關於SearchView,還有一寫額外的設置,好比:
// 設置提交按鈕是否可見(默認不可見) tbSearchSv.setSubmitButtonEnabled(true);
// 設置左側是否顯示搜索圖標(默認不可見) tbSearchSv.setIconifiedByDefault(false);
更多可以使用的API請參考官方文檔:
https://developer.android.google.cn/reference/android/widget/SearchView
不過,咱們這裏還須要作最後一點善後。若是你是一路下來照着本篇文章敲代碼的話,在搜索框打開的狀況下按一下返回鍵,你期待的是什麼?是否是取消搜索操做,停留在當前界面?然而其實是……退出了APP。
因此咱們這裏要對返回鍵的默認動做作一個「攔截」,具體可參考以下代碼片:
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: if (!tbSearchSv.isIconified()) { tbSearchSv.setIconified(true); return true; } break; } return super.onKeyUp(keyCode, event); }
這裏SearchView的isIconfied()方法能夠返回當前的SearchView展開狀態。
4、返回上一層
ToolBar還有一個比較常見的功能就是左上角的返回按鈕,提供返回上一層操做,不少的APP開發者都習慣於自定義一個ImageButton或相似的空間,而後使用美工提供的圖像素材,設置監聽器,寫Selector……一套下來,費時費力。
其實Google已經爲開發者提供了現成的很是易用的返回邏輯處理。要實現這些處理,兩步就搞定了。
1. 在ToolBar對象上啓用返回鈕
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
這裏注意,雖然以前將ToolBar經過setSupportActionBar()方式當作參數被set了一次,可是ToolBar類自己並不提供setDisplayHomeAsUpEnabled()方法,所以,咱們還須要getSupportActionBar(),先獲取ActionBar對象,而後使用該對象,而不是直接使用ToolBar對象。
2. 在AndroidManifest.xml中定義要跳轉的Activity
如題,咱們在AndroidManifest.xml中,對子Activity作處理,這裏不要忘記兼容低版本的系統。
<activity android:name=".MainActivity" android:parentActivityName=".SecondActivity"> <!-- 兼容 Android4.0 及如下版本--> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".SecondActivity" /> </activity>
將SecondActivity改成入口Activity,而後從新運行程序,將實現以下效果:
到此,關於ToolBar常見用法的梳理告一段落。源碼請自取:
https://github.com/wh1990xiao2005/JetpackDemo
我會在接下來的文章中,和你們分享關於ToolBar的剩餘內容,以及AppCompat兼容包中的其餘知識,但願對你我都有幫助。 共勉!