因为最近在写一个表情包的项目,刚开始写UI的时候就把每个页面的头部都用了toolbar,原因就是我想主题颜色都是一种的,用ToolBar更方便,但是呢,看了一个大佬的代码后发现自己的想法真的是太。。。 然后自己又去网上找了好多优秀的项目,看了看别人的使用,下面就一步步说toolbar。
ToolBar的进阶历程
- Toolbar的基本使用
- Toolbar的进阶使用
- 项目中的Toolbar
Toolbar的基本使用
首先我们要将ActionBar隐藏。像下面这样
- 隐藏ActionBar
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
或者
<style name="NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
主题的样式就可以通过colorPrimary、colorPrimaryDark、colorAccent来修改。
- 设置ToolBar
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/dodgerblue"
app:navigationIcon="@mipmap/back"
app:titleTextColor="@color/colorWhite"
app:title="知乎">
</android.support.v7.widget.Toolbar>
toolbar有些常用的属性介绍一下:
- android:background 设置背景颜色
- app:navigationIcon 上图返回图标的设置
- app:title 设置显示的标题
- app:titleTextColor 设置标题的颜色
- app:subtitle 设置副标题
- app:subtitleTextColor 设置副标题颜色
- app:logo 设置Logo(返回图标和标题之前还有个logo)
Toolbar的进阶使用
有关导包
在初始化Toolbar的时候一般有两个
Toolbar(android.support.v7.widget)
Toolbar(android.widget)
这里需要导入V7的包!!!否则,可能会找不到Toolbar这个类。
- Toolbar标题的居中
如果在toolbar里加入TextView的话想让标题居中,就需要设置layout_gravity="center",若是想靠左就layout_gravity="left",靠右就layout_gravity="right"
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/dodgerblue"
app:navigationIcon="@mipmap/back"
app:titleTextColor="@color/colorWhite"
app:title="知乎">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="toolbar"
android:textColor="@color/colorWhite"
android:textSize="22sp"/>
</android.support.v7.widget.Toolbar>
因为Toolbar是一个继承ViewGroup的控件,这就说明它是可以有内部控件的!
menu的设置
设置menu其实很简单,在bottomnavigationview(底部导航栏)的使用时也设置了相应的menu。Toolbar集成menu需要重写Activity的 boolean onCreateOptionsMenu(Menu menu) 方法,此方法返回一个boolean,用来判断你是否创建了相应的nenu文件。
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.toolbar_menu,menu);
return true;
}
menu文件
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/app_bar_search"
android:title="搜索"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_cycling"
android:icon="@drawable/find"
android:title="扫一扫"
app:showAsAction="never" />
<item
android:id="@+id/collection"
android:title="我的收藏"
app:showAsAction="never" />
</menu>
其中showAsAction可接受的值有: 这个属性可接受的值有:
- always:使菜单项一直显示在ToolBar上。
- ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。
- never:使菜单项永远都不出现在ToolBar上,在…的子项中显示。
- withText:使菜单项和它的图标,菜单文本一起显示
现在menu并没有显示出来,因为不设置Actionbar是没有办法关联menu文件的。所以
public void setToolBar(){
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.toolbar_menu,menu);
return true;
}
setSupportActionbar(toolbar) 这一行代码千万不能忘,否则menu是显示不出来的!!!
我们现在发现...和搜素的图标都是黑色的和白色的字体很很不搭,而且点开...是这样的。。。
修改menu弹出的位置和样式
Toolbar有一个属性 popuptheme="@style/ToolbarPopupTheme" 这个属性是给Toolbar设置主题的!
- 修改弹出框的文字样式、popup背景的样式
<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:background">#ffffff</item><!--设置弹框背景颜色-->
<item name="android:textColorPrimary">#000000</item><!--设置文字颜色-->
<item name="android:textSize">16sp</item><!--设置文字大小-->
</style>
- 修改弹出框的位置问题
<style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:background">#ffffff</item>
<item name="android:textColorPrimary">#000000</item>
<item name="android:textSize">16sp</item>
<item name="actionOverflowMenuStyle">@style/OverflowMenuTheme</item>
</style>
<style name="OverflowMenuTheme" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="overlapAnchor">false</item>><!--这个属性设置为false,就能使得popup在Toolbar的下面显示-->
</style>
位置文字颜色设置了,但是溢出菜单和搜索那个按钮太丑了
- 修改溢出菜单的颜色
修改溢出菜单就是要修改相应的主题样式,就是在文章开始修改的主题,只要在上面加上 item name="android:textColorSecondary"... 就可以了。
<!-- Base application theme. -->
<style name="AppTheme.NoActionBar" 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>
<item name="android:textColorSecondary">#ffffff</item>
</style>
一些相应的监听
设置监听分为两种 1.设置ActionBar的监听(针对menu的开发内容)2.针对Toolbar内部设置的控件和navigationIcon的监听
- menu的监听
对于menu的监听 onOptionItemSelected(MenuItem item) 这个方法,和onClickListener的监听都类似
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_find:
Toast.makeText(this, "扫一扫", Toast.LENGTH_SHORT).show();
break;
case R.id.menu_colection:
Toast.makeText(this, "收藏", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
- 返回的监听
因为大部分的应用都会在此处处理返回的逻辑。google也早就设计好了,所以把navigationIcon的监听单独到Toolbar身上了
public void setToolbarListener(){
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
项目中的Toolbar
我觉得一个项目成功的开始就在于UI,UI的美观真的很重要,而且还要考虑加载UI时间的问题(从自己做项目开始才开始考虑这些问题 笑哭==),之前一直让我很困扰的是项目里的头部(就是类似在toolbar的位置上的那些控件开始如何摆放的),最开始我是该每个控件加背景用相对布局,之后学会toolbar开始在toolbar里放控件,但是发现一个问题,toolbar里会被限制,有好多空间的位置不好确定,后来去看了别人的项目才发现toolbar一般都是被重写的,目的是为了重复利用,因为有好多的页面他们的toolbar的布局是一样的,只是控件的样式发生了改变,这里面标签就有了很大的用处。
上面说到了toolbar的重写,也就是自定义view,toolbar可以继承LinearLayout,也可以直接继承toolbar。下面是继承Linearlayout的一种写法,我在项目中学到的。
public class Toolbar extends LinearLayout implements View.OnClickListener {
TextView title;
ImageView back;
public ImageView right1,right2;
public Toolbar(Context context) {
super(context);
initViews();
}
public Toolbar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initViews();
}
public Toolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initViews();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public Toolbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initViews();
}
private void initViews() {
View view = LayoutInflater.from(getContext()).inflate(R.layout.widget_toolbar, this, false);
addView(view);
title = findViewById(R.id.title);
right1 = findViewById(R.id.right1);
right2 = findViewById(R.id.right2);
findViewById(R.id.back).setOnClickListener(this);
if (((Activity) getContext()).getTitle() != null) {//判断该Activity标题是否为空,不为空设置到标题
title.setText(((Activity) getContext()).getTitle());
}
setRightButtonOneShow(false);//按钮不可见(GONE)
setRightButtonTwoShow(false);//按钮不可见(GONE)
}
//设置标题
public void setTitle(String title) {
this.title.setText(title);
}
//设置分享按钮是否显示
private void setRightButtonOneShow(boolean visibility){
int i = visibility? View.VISIBLE:View.GONE;
right1.setVisibility(i);
}
private void setRightButtonTwoShow(boolean visibility){
int i = visibility? View.VISIBLE:View.GONE;
right2.setVisibility(i);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back:
((Activity) getContext()).finish();
break;
}
}
}
这里就是重写的代码,initViews()里初始化了布局中的控件,不想显示的可以隐藏,有兴趣的可以看看标签,用于隐藏某些控件。
下面是.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/back"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/selectableItemBackground"
android:padding="15dp"
android:src="@drawable/back" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:text="标题"
android:textColor="@color/colorBlack"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/right1"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/selectableItemBackground"
android:padding="15dp"
android:src="@drawable/share" />
<ImageView
android:id="@+id/right2"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/selectableItemBackground"
android:padding="15dp"
android:src="@drawable/share" />
</LinearLayout>
加油哇!!!