这一篇我们介绍两个相似的控件,分别是Actionbar和Toolbar。
Actionbar是Android3.0之后的一个重要的交互元素,Actionbar位于Activity的顶部,用于显示图标、菜单、标题,广泛用于View的交互、导航等功能。在Android3.0之后,Actionbar是默认添加的,只要你新建的Activity继承于AppCompatActivity,Actionbar是默认添加的。
我们看一下theme主题配置文件中的样式,图片来源于网络
Android3.0是默认添加Actionbar的,我们讲一下Actionbar的移除
在Activity的属性中设置主题风格为NoTitleBar
例如:
在代码中修改,通过在代码中调用下面一句代码,可以隐藏Actionbar
getSupportActionBar().hide();
注意的是:这一句是当前的Activity继承与AppcompatActivity的时候,如果是直接继承于Activity的话,需要在setContent()之前调用:
requestWindowFeature(Window.FEATURE_NO_TITLE)
介绍完Actionbar的添加和移除,下面我们来介绍一下Actionbar的使用
我们可以在代码中,通过调用getSupportActionBar()获取到Actionbar实例对象,然后通过相应的方法设置一些属性,Actionbar的属性设置方法有:
show()方法:显示Actionbar
setTitle(CharSequence title)方法:设置Actionbar的标题,重载方法有:setTitle(int resId)
setSubtitle(CharSequence subtitle)方法:设置Actionbar的字幕,重载方法有:setSubtitle(int resId)
setSplitBackgroundDrawable(Drawable d)方法:设置Actionbar的分隔背景
setStackedBackgroundDrawable(Drawable d)方法:设置Actionbar的重叠背景
setLogo(Drawable logo)方法:设置Actionbar的logo,重载方法是:setLogo(int resId)
setIcon(Drawable icon)方法:设置Actionbar的icon,重载方法是:setIcon(int resId)
setHomeButtonEnabled(boolean enabled)方法:设置是否允许返回按钮
setHomeAsUpIndicator(Drawable indicator)方法:设置显示一个返回图片
setHomeActionContentDescription(CharSequence description)方法,当允许的时候,设置返回上一个Activity的描述信息,重载方法是:setHomeActionContentDescription(int resId)
setHideOnContentScrollEnabled(boolean hideOnContentScroll)方法:设置在内容滚动的是时候是否显示Actionbar
setDisplayShowTitleEnabled(boolean showTitle)方法:设置是否显示标题
setDisplayUseLogoEnabled(boolean useLogo)方法:设置是否显示logo
setDisplayShowHomeEnabled(boolean showHome)方法:设置是否显示返回
setDisplayShowCustomEnabled(boolean showCustom)方法:设置是否显示一个自定义View
setDisplayOptions(int options)方法:设置显示的选项
setDisplayOptions(int options, int mask)方法:设置选中的选项
setCustomView(View view)方法:设置自定义的View,重载:setCustomView(View view, ActionBar.LayoutParams layoutParams)
setBackgroundDrawable(Drawable d)方法:设置背景
removeOnMenuVisibilityListener(ActionBar.OnMenuVisibilityListener listener)方法:移除一个可见的菜单时的监听
hide()方法:隐藏Actionbar
getTitle()方法:获取标题
简单的介绍一下Actionbar的常用方法,我们获取到Actionbar的实例之后可以调用这些方法去设置相应的属性,这里就不在做详细的代码演示了
将Actionbar中所有的ActionItem定义在menu中,主要讲item的几个属性:
title属性:设置标题
icon属性:设置图标
showAsAction属性:设置Item的显示方式,有几个值可以选择:ifRoom,当有4个或者4个以上的时候显示在overflow里面;always,总是显示所有的item;never,不会显示;withText,尽可能显示,可能显示不全;collapseActionView,折叠在一个按钮里面,点击按钮会显示,一般与ifRoom一起使用。
下面我们用一个例子讲解一下:
首先是menu资源文件:
这里我们有5个,所以用了ifRoom属性。需要在Activity中重写两个方法:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_app:
ToastUtil.showToast(this, "苹果");
break;
case R.id.menu_vitis:
ToastUtil.showToast(this, "葡萄");
break;
case R.id.menu_banana:
ToastUtil.showToast(this, "香蕉");
break;
case R.id.menu_pineapple:
ToastUtil.showToast(this, "菠萝");
break;
case R.id.menu_orange:
ToastUtil.showToast(this, "橘子");
break;
}
return super.onOptionsItemSelected(item);
}
onCreateOptionsMenu(Menu menu)方法是将menu挂载到Actionbar中,onOptionsItemSelected(MenuItem item)方法是对item选中进行处理
实现的效果是:
布局资源文件代码:
这里的布局文件比较简单,就直接显示两个文本,可以按需要做更复杂的布局,这里只是演示,接下来是Activity中的代码:
private TextView bar_title;
private TextView bar_right;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayUseLogoEnabled(true);
//设置显示自定义的View,如果不设置这个属性,自定义的View不会起作用
actionBar.setDisplayShowCustomEnabled(true);
View view = LayoutInflater.from(this).inflate(R.layout.custom_action_bar, null);
bar_title = (TextView) view.findViewById(R.id.bar_title);
bar_right = (TextView) view.findViewById(R.id.bar_right);
actionBar.setCustomView(view);
bar_title.setText("第三个Activity");
bar_title.setTextColor(Color.WHITE);
bar_right.setText("搜索");
bar_right.setTextColor(Color.WHITE);
setContentView(R.layout.activity_third);
}
在这里,记住必须要调用这个setDisplayShowCustomEnabled(true)方法,设置为true,否则自定义的View不会起作用
实现效果
这里只是比较简单地实现一下自定义Actionbar中的View。还有一个常用的就是可以打开Actionbar的返回图标,只需要在actionbar中调用setDisplayHomeAsUpEnabled(true)设置为true,然后在onOptionsItemSelected(MenuItem item)中监听点击返回图标,然后做出相应的操作就可以了,我们用例子说明一下:
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
这里监听的id必须是android.R.id.home,我们在这里操作就是点击图标就finish掉当前的Activity,实现的效果是:
Actionbar就简单介绍到这里,如果你有其他更好的用法,欢迎留言交流!
Toolbar是Android5.0之后推出的一个符合Material Design风格的导航控件,google推荐我们使用这个代替Actionbar,与Actionbar相比,Toolbar更加灵活,不会只局限于固定在页面顶部,可以固定在页面的任何地方。除此之外,google在设置Toolbar的时候给我们开发者预留了许多可以定制Toolbar的地方,下面我们来一起学习一下Toolbar这个控件吧!
根据官方文档的介绍,Toolbar提供给我们开发者很大的修改余地,例如:
设置导航栏图标
设置App的logo
支持设置标题和子标题
支持添加一个或多个的自定义控件(Toolbar是一个ViewGroup,我们可以添加多个控件)
支持Action Menu
我们先来学习一下Toolbar里面的属性设置方法:
注意的是:Toolbar是google在Android API21的时候推出的,所以AndroidAPI低于21的需要引入 appcompat-v7支持包,否则在低版本上不能用。
使用Toolbar之前,需要在Activity中去掉原来的Actionbar,移除Actionbar的方法在上面我们介绍Actionbar的时候介绍过,这里就不在做介绍了,注意的一个是:
如果Activity是继承AppCompatActivity的话,可以调用下面一句代码:supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
如果是继承Activity的话,可以直接调用: requestWindowFeature(Window.FEATURE_NO_TITLE)
去掉Actionbar之后,就可以正常使用Toolbar了,下面,我们介绍一下Toolbar的简单使用:
布局文件代码:
Activity代码:
public class ToolbarTestActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_tool_bar_test);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
public static void startActivity(Context mContext) {
mContext.startActivity(new Intent(mContext, ToolbarTestActivity.class));
}
}
实现效果:
这里实现的效果跟Actionbar一样,也没有什么可以详细说的,下面我们用Toolbar实现一个比较复杂的效果,在这个实例中,我们整合ToolBar,DrawerLayout,ActionBarDrawerToggle一起实现。
首先看一下效果图:
下面我们看一下具体的代码:
首先是布局资源文件代码:
这里是左边策滑出来页面的布局文件,有点复杂,实现的效果好一点,下面我们看一下Activity的代码:
package com.example.huawen.asdebug;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import java.util.Iterator;
import java.util.LinkedHashMap;
/**
* Created by Huawen on 2016/9/2.
*/
public class ToolbarDemoActivity extends AppCompatActivity implements View.OnClickListener {
private DrawerLayout drawerlayout;
private Toolbar mToolbar;
private ActionBarDrawerToggle mActionBarDrawerToggle;
private TextView tv_left_music;
private TextView tv_left_movie;
private TextView tv_left_novel;
private TextView tv_left_image;
private TextView tv_left_article;
private TextView tv_left_about;
private TextView tv_left_setting;
private FragmentManager mFragmentManager;
private LinkedHashMap mFragments = new LinkedHashMap<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_toolbar_demo);
mToolbar = (Toolbar) findViewById(R.id.toolbar_demo);
setSupportActionBar(mToolbar);
drawerlayout = (DrawerLayout) findViewById(R.id.drawerlayout);
mActionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerlayout, mToolbar, R.string.open, R.string.close);
mActionBarDrawerToggle.syncState();
tv_left_music = (TextView) findViewById(R.id.tv_left_music);
tv_left_movie = (TextView) findViewById(R.id.tv_left_movie);
tv_left_novel = (TextView) findViewById(R.id.tv_left_novel);
tv_left_image = (TextView) findViewById(R.id.tv_left_image);
tv_left_article = (TextView) findViewById(R.id.tv_left_article);
tv_left_about = (TextView) findViewById(R.id.tv_left_about);
tv_left_setting = (TextView) findViewById(R.id.tv_left_setting);
tv_left_music.setOnClickListener(this);
tv_left_movie.setOnClickListener(this);
tv_left_novel.setOnClickListener(this);
tv_left_image.setOnClickListener(this);
tv_left_article.setOnClickListener(this);
tv_left_about.setOnClickListener(this);
tv_left_setting.setOnClickListener(this);
mFragmentManager = getSupportFragmentManager();
//设置首选项
changeFragment(MainFragment.POSITION_MUSIC);
}
public static void startActivity(Context mContext) {
mContext.startActivity(new Intent(mContext, ToolbarDemoActivity.class));
}
/**
* 切换Fragment
*
* @param position
*/
public void changeFragment(int position) {
FragmentTransaction transaction = mFragmentManager.beginTransaction();
hideAllFragment(transaction);
drawerlayout.closeDrawer(Gravity.LEFT);
MainFragment mainFragment = mFragments.get(position);
if (mainFragment == null) {
mainFragment = new MainFragment(position);
transaction.add(R.id.main_content, mainFragment);
mFragments.put(position, mainFragment);
} else {
transaction.show(mainFragment);
}
transaction.commit();
}
/**
* 先隐藏所有的fragment
*
* @param transaction
*/
private void hideAllFragment(FragmentTransaction transaction) {
if (mFragments != null) {
Iterator iterator = mFragments.entrySet().iterator();
while (iterator.hasNext()) {
LinkedHashMap.Entry entry = (LinkedHashMap.Entry) iterator.next();
MainFragment mainFragment = entry.getValue();
transaction.hide(mainFragment);
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_left_music:
changeFragment(MainFragment.POSITION_MUSIC);
break;
case R.id.tv_left_movie:
changeFragment(MainFragment.POSITION_MOVIE);
break;
case R.id.tv_left_novel:
changeFragment(MainFragment.POSITION_NOVEL);
break;
case R.id.tv_left_image:
changeFragment(MainFragment.POSITION_IMAGE);
break;
case R.id.tv_left_article:
changeFragment(MainFragment.POSITION_ARTICLE);
break;
case R.id.tv_left_about:
changeFragment(MainFragment.POSITION_ABOUT);
break;
case R.id.tv_left_setting:
changeFragment(MainFragment.POSITION_SETTING);
break;
}
}
}
这里的话通过点击相应的条目切换不同的Fragment,将Fragment保存在一个HashMap中,每次切换就先隐藏所有的Fragment,然后再显示点击出来的Fragment,这样达到互斥的效果,接下来看一下 MainFragment的代码:
package com.example.huawen.asdebug;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by Huawen on 2016/9/2.
*/
public class MainFragment extends Fragment {
private TextView mTextView;
private int position;
public static final int POSITION_MUSIC = 1001;
public static final int POSITION_MOVIE = 1002;
public static final int POSITION_NOVEL = 1003;
public static final int POSITION_IMAGE = 1004;
public static final int POSITION_ARTICLE = 1005;
public static final int POSITION_ABOUT = 1006;
public static final int POSITION_SETTING = 1007;
public MainFragment(int position) {
this.position = position;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
mTextView = (TextView) view.findViewById(R.id.tv_main_text);
switch (position) {
case POSITION_MUSIC:
mTextView.setText(R.string.menu_music);
break;
case POSITION_MOVIE:
mTextView.setText(R.string.menu_movie);
break;
case POSITION_NOVEL:
mTextView.setText(R.string.menu_novel);
break;
case POSITION_IMAGE:
mTextView.setText(R.string.menu_image);
break;
case POSITION_ARTICLE:
mTextView.setText(R.string.menu_article);
break;
case POSITION_ABOUT:
mTextView.setText(R.string.menu_about);
break;
case POSITION_SETTING:
mTextView.setText(R.string.menu_setting);
break;
}
return view;
}
}
MainFragment里面就是根据点击的位置,显示不同的文本,这里就让他显示一个文本,做一个演示。如果各位有需要可以根据这个做一个比较复杂的布局。
这里就不在做很多的描述了,最后总结一下Toolbar使用过程中的一些坑:
有时在Xml中设置属性不生效,用相应的Java方法设置或者在根布局加入自定义属性的命名空间,例如xmlns:toolbar=”http://schemas.android.com/apk/res-auto”
改变字体颜色,自定义theme,设置actionMenuTextColor无效,将actionMenuTextColor换成android:textColorPrimary 即可
这里只是一些坑还有其他的欢迎留言交流!
附上Demo的下载地址:http://download.csdn.net/detail/solo_talk/9620141
附上Actionbar的国内镜像API地址
附上Toolbar的国内镜像API地址
这两个都是V7包中的,跟APP包中的没差!