Android学习笔记044之Actionbar和Toolbar

 这一篇我们介绍两个相似的控件,分别是Actionbar和Toolbar。

Actionbar

  Actionbar是Android3.0之后的一个重要的交互元素,Actionbar位于Activity的顶部,用于显示图标、菜单、标题,广泛用于View的交互、导航等功能。在Android3.0之后,Actionbar是默认添加的,只要你新建的Activity继承于AppCompatActivity,Actionbar是默认添加的。

我们看一下theme主题配置文件中的样式,图片来源于网络

Android3.0是默认添加Actionbar的,我们讲一下Actionbar的移除

Actionbar的移除

  1. 在Activity的属性中设置主题风格为NoTitleBar

    例如:
    
  2. 在代码中修改,通过在代码中调用下面一句代码,可以隐藏Actionbar

    getSupportActionBar().hide();
    
  3. 注意的是:这一句是当前的Activity继承与AppcompatActivity的时候,如果是直接继承于Activity的话,需要在setContent()之前调用:

    requestWindowFeature(Window.FEATURE_NO_TITLE)
    

介绍完Actionbar的添加和移除,下面我们来介绍一下Actionbar的使用

Actionbar的使用

1、修改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的实例之后可以调用这些方法去设置相应的属性,这里就不在做详细的代码演示了

2、添加item和overflow

将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选中进行处理

实现的效果是:

3、在Actionbar中添加自定义View

布局资源文件代码:







    

    




这里的布局文件比较简单,就直接显示两个文本,可以按需要做更复杂的布局,这里只是演示,接下来是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

概述

  Toolbar是Android5.0之后推出的一个符合Material Design风格的导航控件,google推荐我们使用这个代替Actionbar,与Actionbar相比,Toolbar更加灵活,不会只局限于固定在页面顶部,可以固定在页面的任何地方。除此之外,google在设置Toolbar的时候给我们开发者预留了许多可以定制Toolbar的地方,下面我们来一起学习一下Toolbar这个控件吧!

根据官方文档的介绍,Toolbar提供给我们开发者很大的修改余地,例如:

  • 设置导航栏图标

  • 设置App的logo

  • 支持设置标题和子标题

  • 支持添加一个或多个的自定义控件(Toolbar是一个ViewGroup,我们可以添加多个控件)

  • 支持Action Menu

我们先来学习一下Toolbar里面的属性设置方法:

  • collapseActionView()方法:折叠当前展开的View
  • dismissPopupMenus()方法:关闭当前显示的菜单,包括overflow和子菜单
  • generateLayoutParams(AttributeSet attrs)方法:根据提供的属性值获取到新的布局参数
  • getContentInsetEnd()方法:获取结束位置的内容
  • getContentInsetLeft()方法:获取左边的内容
  • getContentInsetRight()方法:获取右边内容
  • getContentInsetStart()方法:获取开始位置的内容
  • getLogo()方法:获取logo
  • getLogoDescription()方法:获取Toolbarlogo的描述信息
  • getMenu()方法:获取menu
  • getNavigationContentDescription()方法:获取导航描述信息
  • getNavigationIcon()方法:获取导航图标
  • getOverflowIcon()方法:获取到overflow的icon
  • getSubtitle()方法:获取到Toolbar的子标题
  • hasExpandedActionView()方法:检测是否有展开的View
  • inflateMenu(int resId)方法:将menu资源inflate到toolbar里面
  • isOverflowMenuShowing()方法:检查是否有显示menu
  • onHoverEvent(MotionEvent ev)方法:处理toolbar的悬停事件
  • onRtlPropertiesChanged(int layoutDirection)方法:文本对齐方式
  • onTouchEvent(MotionEvent ev)方法:处理触摸事件
  • setContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight)方法:设置toolbar绝对位置内容
  • setContentInsetsRelative(int contentInsetStart, int contentInsetEnd)方法:设置toolbar相对位置内容
  • setLogo(int resId)方法、setLogo(Drawable drawable)方法:设置toolbar的logo
  • setLogoDescription(int resId)方法、setLogoDescription(CharSequence description)方法:设置logo的描述信息
  • setNavigationContentDescription(int resId)方法、setNavigationContentDescription(CharSequence description)方法:设置导航按钮的描述信息
  • setNavigationIcon(Drawable icon)方法、setNavigationIcon(int resId)方法:设置导航按钮的图标
  • setNavigationOnClickListener(View.OnClickListener listener)方法:设置导航按钮的监听事件
  • setOnMenuItemClickListener(Toolbar.OnMenuItemClickListener listener)方法:设置menu条目的点击事件
  • setOverflowIcon(Drawable icon)方法:设置overflow的icon
  • setPopupTheme(int resId)方法:设置弹出式菜单的theme
  • setSubtitle(int resId)方法、setSubtitle(CharSequence subtitle)方法:设置toolbar的子标题
  • setSubtitleTextAppearance(Context context, int resId)方法:设置子标题文本的样式
  • setSubtitleTextColor(int color)方法:设置子标题文本颜色
  • setTitle(int resId)方法、setTitle(CharSequence title)方法:设置toolbar的标题
  • setTitleTextAppearance(Context context, int resId)方法:设置toolbar标题文本样式
  • setTitleTextColor(int color)方法:设置标题颜色
  • showOverflowMenu()方法:显示overflow

使用

注意的是: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包中的没差!

你可能感兴趣的:(Android学习)