-
前言
近期在公司做一个全新项目,自然在每个页面都有一个标题栏,脑海中涌出的第一想法肯定是采用Toolbar来实现,然后开始疯狂撸码,结果发现各种碰壁,比如:
1.navigationIcon与左边的间距如何调整?
2.title与navigationIcon间距如何调整?
3.Toolbar中如何使用SearchView?
4.SearchView如何自定义颜色图标文字等?
....
带着这么多疑问开始各种查阅资料,然而里面好多问题之前都遇到并解决过,无奈又忘记了,老是花时间做重复的事情显得有些愚蠢,故抽时间将这些知识点整理一下,既方便自己后续查看也方便广大开发者可以有一个集中的参考。
首先我们得知道ActionBar是Android 3.0的产物,Toolbar是Android 5.0的产物(我没记错吧?),因为ActionBar在国内各大厂商的定制系统下呈现出各种无法统一的效果,故Toolbar的出现,无疑是要一统江湖,取缔ActionBar。OK那就送走ActionBar。
-
开发环境
AndroidStudio 3.0.1
-
各类控件所在包
//均在appcompat包
Toolbar: android.support.v7.widget.Toolbar
SearchView: android.support.v7.widget.SearchView
//添加依赖
implementation 'com.android.support:appcompat-v7:26.1.0'
//均在design包
CollapsingToolbarLayout: android.support.design.widget.CollapsingToolbarLayout
AppBarLayout: android.support.design.widget.AppBarLayout
//添加依赖
implementation 'com.android.support:design:26.1.0'
-
新建项目默认样式
-
修改主题支持Toolbar
默认Application主题的父亲是DarkActionBar,这样我们是不能直接在布局文件里面嵌套Toolbar的,否则会报错:
故,我要给它换一个爹: NoActionBar,这样便可以使用Toolbar:
点开NoActionBar看看里面的内容:
再次运行App,效果如下!感觉秃了顶,太丑了!不能忍,绝对不能忍!!
我要给Ta添加一个Toolbar
-
添加Toolbar
修改布局文件,添加Toolbar控件,这里要注意单独使用Toolbar如果不添加背景色默认是无色的。
效果如图:
-
添加带阴影效果的Toolbar
单纯使用Toolbar会发现下方并没有Z轴的阴影效果,想要有阴影效果,就得将Toolbar放入AppBarLayout中,如下:
看一下效果:
-
设置Toolbar返回箭头
-
调整Toolbar返回箭头左边距
在styles.xml文件里添加下面属性:
然后再到AppTheme里引用该主题
最终效果:
-
添加Toolbar标题
效果:
-
更改标题字体颜色
styles.xml文件新建style
在toolbar布局属性里添加
效果
-
设置Toolbar标题左边距
用到的属性:contentInsetStartWithNavigation
可在布局文件添加:app:contentInsetStartWithNavigation="0dp"
亦可在styles.xml文件配置:
然后:
效果:
其实这个0dp只是一个相对值,它有一个默认最小值,经过我的测试,在52以下,随便设置多少,它都是显示的最小值,大于52则逐渐增加(实际不会谁设计间距这么大,顶多是居中罢了)
-
设置Toolbar标题剧中
貌似Toolbar并没有直接可以设置标题居中显示的属性及api,又因Toolbar实际是个ViewGroup,故在其内部嵌套一个TextView实现居中显示标题
效果如图:
-
Toolbar添加menu
在res文件夹下新建menu目录,在该目录内新建menu文件
在Activity中重写以下方法加载menu文件
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_do_actions, menu);
return super.onCreateOptionsMenu(menu);
}
如果运行无效果,请确保是否初始化Toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("");
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
效果如图:
啧啧啧,黑黢黢的,真TM丑。。。
-
Toolbar中menu图标&样式修改
或许将menu中的图标或者是文字变成白色会好看些吧
方法一:
将menu中文字变成白色,在app主题中加入如下属性: 如图:将右边三点变成白色,同样在主题中加入一条属性:
如图:
方法二:
通过配置Toolbar主题改变图标文字颜色
在布局文件中加入属性:android:theme="@style/ToolbarTheme"
在styles.xml文件新建style
此方法会改变menu中图标和never属性菜单的字体颜色:
-
Toolbar中放入SearchView
在menu菜单中加入:
再将ToolbarTheme里面这条属性修改为白色
效果貌似还不错:
-
修改SearchView的hint文字和颜色
首先要得到SearchView,再调用api设置
private SearchView mSearchView;
private SearchView.SearchAutoComplete mSearchAutoComplete;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_do_actions, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
mSearchAutoComplete = mSearchView.findViewById(R.id.search_src_text);
// mSearchView.setIconified(false); //默认打开搜索框
//设置Hint文字颜色
mSearchAutoComplete.setHintTextColor(ContextCompat.getColor(this,android.R.color.darker_gray));
//设置输入文字颜色
mSearchAutoComplete.setTextColor(ContextCompat.getColor(this,android.R.color.white));
//设置Hint文字
mSearchView.setQueryHint("Hint text here");
//设置是否显示搜索框展开时的提交按钮
mSearchView.setSubmitButtonEnabled(false);
return super.onCreateOptionsMenu(menu);
}
效果图:
-
设置SearchView搜索监听
SearchView输入内容监听
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO: 处理一些输入内容改变的逻辑
return false;
}
});
SearchView关闭按钮监听
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
// TODO: 处理一些关闭搜索框后的逻辑,比如还原之前数据
return false;
}
});
NavigationClickListener关联SearchView,当输入框展开时,点击返回是关闭输入框,否则是关闭当前页面
toolbar.setNavigationOnClickListener(v -> {
if (mSearchAutoComplete.isShown()){
try {
//如果展开则先关闭搜索框
mSearchAutoComplete.setText("");
Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
method.setAccessible(true);
method.invoke(mSearchView);
} catch (Exception e) {
e.printStackTrace();
}
}else{
finish();
}
});
效果图:
如有不完善或者错误之处,希望多多指正。