今天咱们来聊一聊有关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兼容包中的其余知识,但愿对你我都有帮助。 共勉!