www.9778.com 20

【www.9778.com】Android ActionBar

一、ActionBar概述

【www.9778.com】Android ActionBar。ActionBar是androiD3.0以后新增的组件,主要用于标示应用程序以及用户所处的位置并提供相关操作以及全局的导航功能。下面我们就看看如何使用ActionBar,真正使用之前,我们应该首先了解一下ActionBar的结构。

根据官方文档,我们看到整个ActionBar可以分为4个部分,具体如下图:

www.9778.com 1

1、  App
icon:主要用于展示App的Logo,如果当前界面不是一级界面,还可以展示返回导航。

2、  View Control:用于切换不同的视图或者展示非交互信息如app标题等。

3、  Action
Buttons:用于展示app中最重要的操作按钮,如果过多actionbar中放不下则会转移到Action
overflow中,长按会展示操作名称。根据文档说明,Action
Buttons的总宽度不会超过ActionBar的50%。

4、  Action overflow:用于存放展示相对较少使用的操作按钮。

了解了ActionBar的基本结构后,下面我们一起看看如何使用ActionBar。

作者:steven

  1. ActionBar:位于标题栏的位置,要关闭ActionBar
    可以配置android:theme=”@android:style/Theme.Holo.NoActionBar”,也可以调用Actionbar的Hide()函数.ActionBar提供了如下功能:

    • 显示选项菜单的菜单项(将菜单项显示成Action
      Item)
    • 使用程序图标作为返回Home主屏或向上的导航操作

    • 提供交互式View作为Action View

    • 提供基于Tab的导航方式,可以用于切换多个Fragement

    • 提供基于下拉的导航方式

  2. ActionBar无法同时显示所有的菜单项时,Android会根据不同手机设备采取不同行为:
    • 对有menu键的手机,点menu键即可显示剩余菜单项,菜单项无法显示图标
    • 对于没有menu键的手机,android会在最后显示一个折叠图标,用户点击折叠图标就会显示剩余菜单

二、ActionBar的使用

因为actionbar是android3.0之后新增的所以如果在API Level
11以下的版本使用actionBar的话需要导入v7支持包,在这里我们为了兼容低版本需要加入支持包,然后通过以下两个步骤就可以使用ActionBar了。

1、  创建Activity是继承ActionBarActivity

2、 
将app或者Activity的主题设置为@style/Theme.AppCompat.Light

之后运行程序可以看到如下效果图:

 www.9778.com 2

如果不想展示ActionBar,我们可以通过如下代码:

         //取得ActionBar对象
        ActionBar actionBar =getSupportActionBar();
        //调用hide方法,隐藏actionbar
        actionBar.hide();
        //调用show方法,展示actionbar
        //actionBar.show();

根据actionBar的结构,我们先了解App
icon区域的相关操作,此部分主要有两个部分,一部分用于展示Logo,一部分用于展示返回键导航,返回键导航主要操作如下:

1、  返回键导航的显示与隐藏:setDisplayHomeAsUpEnabled(Boolean flag)

2、  返回键导航的图标设置:setHomeAsUpIndicator

3、  返回键的事件处理:重写onOptionsItemSelected方法,做如下判断

if(id==android.R.id.home){

            Toast.makeText(this,"点击了返回!!",Toast.LENGTH_SHORT).show();

            return true;

}

效果图如下:

 www.9778.com 3

Logo区主要操作:

1、  Logo的显示与隐藏:

setDisplayShowHomeEnabled(Boolean flag)

setDisplayUseLogoEnabled(Boolean flag)

2、  Logo的设置:setLogo

设置后效果图如下:

 www.9778.com 4

第二部分是View
Control区,此区域可放置内容比较多,除了用于视图导航的Spinner、tabs、ShareActionProvider,还可以显示标题等信息、自定义View等。本次内容我们先来看看标题部分,其余的下次再做仔细详细介绍。

主要操作:

1、  显示与隐藏标题:setDisplayShowTitleEnabled(Boolean flag)

2、  设置主标题:setTitle

3、  设置副标题:setSubtitle

4、  设定自定义View:setCustomView

显示效果如下图:

 www.9778.com 5

Action Buttons和Action flow
的操作类似,都是用于存放展示操作按钮,那么如何将操作按钮显示在actionbar中呢?

在这里,我们可以分为两步:

1、 
重写onCreateOptionsMenu,此方法用于生成菜单按钮,有两种方式,一种方式编写xml文件,另外一种是java代码生成,这里我们选择编写xml。

2、  重写onOptionsItemSelected,此方法用于响应菜单操作。

Xml内容如下:

<menu 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" tools:context=".MainActivity">
    <item android:id="@+id/action_search" android:title="搜索"
        android:orderInCategory="100" app:showAsAction="always"
        android:icon="@drawable/ic_launcher"/>
    <item android:id="@+id/action_share" android:title="分享"
        android:orderInCategory="100" app:showAsAction="never" />
    <item android:id="@+id/action_collection" android:title="收藏"
        android:orderInCategory="100" app:showAsAction="never" />

    <item android:id="@+id/action_font" android:title="字体大小"
        android:orderInCategory="100" app:showAsAction="never" />
</menu>

ShowAsAction是非常重要的属性,它的值决定了菜单显示区域,分别有never、always、ifroom等

效果如下:

 www.9778.com 6

www.9778.com 7

想要了解更多内容的小伙伴,可以点击下载源码,亲自运行测试。

一、ActionBar:(动作栏)

  1. MenuItem
    title中的内容通常情况下只会在overflow中显示出来,ActionBar中由于屏幕空间有限,默认是不会显示title内容的。但是出于以下几种因素考虑,即使title中的内容无法显示出来,我们也应该给每个item中都指定一个title属性:

    • 当ActionBar中的剩余空间不足的时候,如果Action按钮指定的showAsAction属性是ifRoom的话,该Action按钮就会出现在overflow当中,此时就只有title能够显示了(通过反射调用特殊方法,也可以使图标显示在overflow
      menu中)。
    • 如果Action按钮在ActionBar中显示,用户可能通过长按该Action按钮的方式来查看到title的内容。

    • 屏幕阅读器(盲人使用)可以独处Menu的tit

  2. 如果是在Fragment中添加的menu
    item,那么单击item时会先调用Activity的onOptionsItemSelected然后是Fragment的onOperationsItemSelected

  3. ActionBar除了显示Action
    Item以外,还可以显示普通的UI组件,称为action
    view,这样的item要指定android:showAsAction=”ifRoom|collapseActionView”属性收缩成一个图标item,以减少占用的空间,当点击item时控件会自己展开,如果要为UI组件添加事件处理等,可以用如下方式:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        // Configure the search info and add any event listeners
        ...
        return super.onCreateOptionsMenu(menu);
    }
    

    www.9778.com,可以用如下两种方式:

    • 添加Action
      Item时,设置android:actionViewClass指定Action View的实现类
    • 添加Action
      Item时,使用android:actionLayout指定Action
      View对应的视图资源
  4. 选项菜单中能够加到Actionbar中直接显示的item一般要满足下列条件之一,而Help,Setting,FeedBack等要放到overflow
    menu中

    • 经常使用
    • 重要
    • 典型 
  5. Android
    4.0开始支持split actionbar,split
    actionbar会在屏幕底部显示一部分menu
    item,以确保顶部actionbar有足够空间显示icon和title等,对于Tab导航的actionbar,隐藏actionbar的title和icon,使用split
    actionbar可以使tab导航显示在屏幕最顶部。在<activity>或<application>元素中设置uiOptions="splitActionBarWhenNarrow"支持split actionbar,使用在低于4.0的android也可以使用android:uiOptions属性,系统不识别该属性就会使用之前版本的actionbar布局
  6. ActionBar调用setHomeButtonEnabled使图标变为可点击的按钮(也可以理解为menu
    item),menu
    id为android.R.menu.home(系统id),可以在onOptionsItemSelected中处理该单击事件,行为应该是下面行为之一:

    • 返回application的主activity(navigating
      back)

      Intent intent = new Intent(this, HomeActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
      
    • 返回application的上一层(navigating
      up)

  7. setHomeButtonEnabled使应用程序图标可以点击,setDisplayHomeAsUpEnabled函数(Android
    4.0后才有)在应用程序图标上加上向左的箭头并使图标可点击,对应ActionBar.DISPLAY_HOME_AS_UP,
    行为是navigating up,要注意的是navigating up的行为同navigating
    back(返回按钮的行为)行为一样都要自己在onOptionsItemSelected中实现,与navigating
    back行为的区别是:
    www.9778.com 8
    www.9778.com 9
  8. Action
    Provider:如同action view一样,action provider也可以替代action
    item,它可以自定义item的appearance和behaviors,还可以为item创建submenu.自定义ActionProvider要实现的函数:

    • ActionProvider():构造函数,会传Context参数,用于其他函数
    • onCreateActionView():为action
      item定义action
      view,可以使用Context获取一个LayoutInflater,然后填充action
      view

      public View onCreateActionView() {
          // Inflate the action view to be shown on the action bar.
          LayoutInflater layoutInflater = LayoutInflater.from(mContext);
          View view = layoutInflater.inflate(R.layout.action_provider, null);
          ImageButton button = (ImageButton) view.findViewById(R.id.button);
          button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // Do something...
              }
          });
          return view;
      }
      
    • onPerformDefaultAction():menu
      item在overflow
      menu中时,点击item执行的action,如果通过onPrepareSubMenu()函数创建了submenu,则点击overflow
      menu中的item时不会执行onPerformDefaultAction,而是会弹出submenu。如果Activity或Fragment实现了onOptionsItemSelected()函数并返回True,onPerformDefaultAction()也不会被调用

    • onPrepareSubMenu():创建与指定了ActionProvider的menu
      item关联的submenu.只有当hasSubMenu函数返回True时该方法才执行

(一)、简介:(扩展TitleBar)

  1. ShareActionProvider:为actionbar提供一个share
    action,比如为短信引用或者社交应用分享照片,需要配置actionProviderClass属性,

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/menu_share"
              android:title="@string/share"
              android:showAsAction="ifRoom"
              android:actionProviderClass="android.widget.ShareActionProvider" />
        ...
    </menu>
    

    ShareActionProvider实现了创建子菜单,弹出显示分享目标应用,处理单击事件等逻辑,根据用户选中的频率,ShareActionProvider为每个分项目标都保存了一个优先级,优先级高的保存在列表靠前的位置,使用最多的应用作为默认分享目标直接显示在actionbar上,优先级信息默认是存放在一个私有文件中,文件名为DEFAULT_SHARE_HISTORY_FILE_NAME指定.使用ShareActionProvider的步骤通常为:

    • 获取ShareActionProvider对象

      mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
      
    • 调用ShareActionProvider.setShareIntent(Intent)方法,Intent参数的action必须是ACTION_SEND,并带有附加数据,如果EXTRA_TEXT,EXTRA_STREAM等

      ShareActionProvider  @Override
        public boolean onCreateOptionsMenu(Menu menu) {
              // Inflate the menu; this adds items to the action bar if it is present.
              getMenuInflater().inflate(R.menu.main, menu);
              // Get the ActionProvider for later usage
              provider = (ShareActionProvider) menu.findItem(R.id.menu_share)
                      .getActionProvider();
             //必须要在菜单点击前调用doShare,不然菜单没办法点击
              doShare();
              return true;
          }
         public void doShare() {
              // populate the share intent with data
              Intent intent = new Intent(Intent.ACTION_SEND);
              intent.setType("text/plain");
              intent.putExtra(Intent.EXTRA_TEXT, "This is a message for you");
              provider.setShareIntent(intent);
          }
      

Action
bar(动作栏)是一个导航控件,用以代替传统屏幕顶端的标题栏。ActionBar显示在屏幕顶部的控件,它包括了在左边显示的应用的logo图标和右边操作菜单的可见项。类似于windows桌面程序的工具栏。

  1. ActionBar
    Tab导航的实现步骤如下:

    • 调用ActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TAB)设置使用tab导航
    • 调用ActionBar.addTab方法添加多个tab标签,并为每个tab标签添加事件监听器.系统会根据屏幕大小自动调整tabs,大屏在action
      bar上显示,小屏在单独的bar上显示,称为stacted action bar
      www.9778.com 10
      www.9778.com 11
  2. ActionBar还提供了下拉式导航方式,需要调用setNavigationg(ActionBar.NAVIGATON_MODE_LIST)方法设置使用下拉列表导航方式,调用setListNavigationCallbacks添加列表,并为每个列表设置事件监听器

效果如下图:

www.9778.com 12

actionbar

1、ActionBar主要功能:

Action
Bar被认为是新版Android系统中最重要的交互元素,在程序运行中一直置于顶部,主要起到的作用在于:

1)突出显示一些重要操作(如“注册”、“登录”、“搜索”等)。将平时隐藏的选项菜单显示成活动项ActionItem。

2)在程序中保持统一的页面导航和切换方式。这种基于Tab的导航方式,可以切换多个Fragment。

3)提供基于下拉的导航菜单。

4)使用程序logo,作为返回APP的HOME主页面或向上的导航操作。

2、ActionBar分成四个区域:

www.9778.com 13

ActionBar

•App
Icon:可显示APP的icon,也可用其他图标代替。当软件不在最高级页面时,图标左侧会显示一个左箭头,用户可以通过这个箭头向上导航。

•视图切换:(效果如下图)

•Action Buttons:这个放最重要的软件功能,放不下的按钮就自动进入Action
overflow了。

•Action overflow:不常用的操作项目自动进入Action overflow

www.9778.com 14

overflow

【备注:】什么是Action overflow

对于没有MENU按键的手机,ActionBar会在最后显示一个折叠的图标,点击该图标会显示剩余的选项菜单项。这个折叠的图标功能就是Action
overflow。

Action
overflow中存放并不会频繁用到的操作。按照官方网页上的说法,“Overflow图标仅显示在没有MENU硬按键的手机上,而对于有MENU键的手机,

overflow图标是不显示的,当用户点击MENU按键时弹出。”  事实上Google已经敦促手机厂商及软件开发商取消MENU菜单。也就是以前的Menu将不再使用。

(二)、创建ActionBar:

1、XML资源文件中定义menu。同样可以有普通菜单、二级普通菜单、二级可选项菜单。

www.9778.com 15

创建actionbar

android:showAsAction属性值的解释:

•never: 不将该MenuItem显示在ActionBar上(是默认值)

•always: 总是将该MenuItem显示在ActionBar上

•ifRoom: 当AcitonBar位置充裕时将该MenuItem显示在ActionBar上

•withText:
将该MenuItem显示在ActionBar上,并显示该菜单项的文本。但是只在宽屏状态下显示。

•collapseActionView  : 将该ActionView折叠成普通菜单项。最低API=14

多个属性可以同时使用,使用“|”分隔。

(三)、启动程序图标导航:(就是让APP的LOGO也变成可以点击的导航图标。)

核心代码如下:

www.9778.com 16

启动程序图标导航

代码解释:

1.actionBar =getActionBar();    获取ActionBar对象。

2.actionBar.setDisplayHomeAsUpEnabled(true);      设置是否将LOGO图标转成可点击的按钮,并在图标前添加一个向左的箭头。

3.actionBar.setHomeButtonEnabled(true);      设置是否将LOGO图标转变成可点击的按钮。

4.actionBar.setDisplayShowHomeEnabled(true);     设置是否显示LOGO图标。

(四)、ActionBar中添加Action View:

1、Action的学习要掌握如何将选项菜单显示成Action Item;

2、要掌握如何启动程序Logo导航;

3、ActionBar还可以添加Action View。

调用方式1为:在xml文件中写上android:actionLayout=”@layout/布局名”。

调用方式2为:在xml文件中写上android:actionViewClass=”android.widget.SearchView”。

4、示例代码:

核心代码如下:

www.9778.com 17

ActionBar中添加Action View:

www.9778.com 18

显示时钟的布局

(五)、ActionBar在窗体底部显示:

在清单配置文件中设置android:uiOptions属性为:splitActionBarWhenNarrow

可以在application或者activity节点中。

1、核心代码:

www.9778.com 19

ActionBar在窗体底部

(六)、ActionBar的导航模式:

1、TAB标签导航模式:

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TAB);

2、下拉列表导航模式:

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

(七)、ActionBar保护现场:

1、目的:当横竖屏切换时,会让页面重新加载。在tab模式下,如何记住之前的tab索引呢?需要保护现场。

2、核心代码:

www.9778.com 20

ActionBar保护现场

(八)、横竖屏切换时的生命周期问题的解决(android:configChanges属性)

对android:configChanges属性,一般认为有以下几点:

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

但是,自从Android 3.2(API
13),在设置Activity的android:configChanges=”orientation|keyboardHidden”后,还是一样
会重新调用各个生命周期的。因为screen
size也开始跟着设备的横竖切换而改变。所以,在AndroidManifest.xml里设置的MiniSdkVersion和
TargetSdkVersion属性大于等于13的情况下,如果你想阻止程序在运行时重新加载Activity,除了设置”orientation”,
你还必须设置”ScreenSize”。

解决方法:AndroidManifest.xml中设置android:configChanges=”orientation|screenSize“