当前位置: 代码迷 >> Android >> Android API Guides-Action Bar
  详细解决方案

Android API Guides-Action Bar

热度:577   发布时间:2016-04-24 11:08:16.0
Android API Guides---Action Bar

Action Bar

操作栏是一个窗口功能,可识别用户的位置,并提供用户操作和导航模式。使用操作栏,您的用户在不同应用程序熟悉的界面,该系统正常适应不同的屏幕配置。



图1.一个操作栏,其中包括[1]应用程序图标,[2]两项行动项目,和[3]操作溢出。
操作栏提供了几个关键功能:
提供了应用程序给你的应用的身份,并表示用户位置的专用空间。
使重要行动显明易在可预见的方式(如搜索)。
支持应用内一致的导航和查看开关(带标签或下拉列表)。
有关操作栏中的互动模式和设计准则的详细信息,请参阅操作栏的设计指南。
在Android 3.0的(API级别11)首先添加的动作条的API,但他们也可以在支持图书馆与Android 2.1(API 7级)及以上的兼容性。
本指南重点介绍如何使用支持库行动起来吧,但如果您的应用程序仅支持的Andr??oid 3.0或更高版本,您应在框架使用的ActionBar的API。大部分的API都是相同的,但居住在不同的包命名空间有几个例外到在下面的章节提到的方法名称或签名。
注意:务必从相应的包导入动作条类(及相关API):
如果低于11支持API级别:
import android.support.v7.app.ActionBar
如果只支持API级别11和更高版本:
import android.app.ActionBar
注意:如果你正在寻找关于上下文显示行动项目上下文操作栏的信息,请参阅菜单指南。

添加操作栏


如上所述,本指南重点介绍如何在支持库使用的ActionBar的API。所以,如果你可以添加操作栏,则必须按照在支持库设置的指示成立了以应用程序兼容性V7支持库项目。


一旦你的项目设置与支持库,这里是如何添加操作栏:


通过扩展ActionBarActivity创建活动。
使用(或扩展)的Theme.AppCompat主题,为您的活动之一。 例如:

<activity android:theme="@style/Theme.AppCompat.Light" ... >
现在,你的活动在Android2.1(API7级)以上运行时,包括操作栏。
在API级别11或更高版本
操作栏包含在使用Theme.Holo主题(或者它的后代之一),这是默认的主题时,无论是targetSdkVersion VS的minSdkVersion属性被设置为“11”或更高的所有活动。如果你不想为活动的操作栏,设置活动主题Theme.Holo.NoActionBar。
拆除行动起来吧
你可以通过调用隐藏隐藏在运行时操作栏中的()。 例如:

ActionBar actionBar = getSupportActionBar();actionBar.hide();
在API级别11或更高版本
获取与getActionBar()方法的动作条。
当操作栏隐藏,系统会调整您的布局,填补了屏幕空间现在可用。您可以通过拨打节目带来的操作栏回()。


要注意的是隐藏和删除操作栏使你的活动重新布局,以考虑通过操作栏占用的空间。如果你的活动往往隐藏和显示操作栏,您可能希望启用覆盖模式。覆盖模式吸引你的活动布局前面的操作栏,模糊的顶部。这样一来,你的布局操作栏隐藏和重新出现时保持固定。要启用覆盖模式,为您的活动自定义主题,并设置windowActionBarOverlay为true。欲了解更多信息,请参见下面的章节关于样式化操作栏。


使用标志代替图标


默认情况下,系统使用操作栏中的应用程序图标,通过在<应用>或<活动>元素的图标属性指定。但是,如果您还指定标识属性,那么操作栏使用的标志图片代替图标。


一个logo通常应比图标宽,但不应该包括不必要的文字。您通常应该使用一个标志,只有当它代表你的品牌在用户认识到传统的格式。一个很好的例子是YouTube应用的标志,徽标代表了预期的用户品牌,而应用程序的图标是一个修改后的版本符合的启动器图标方的要求。


添加行动项目




图2.操作栏有三个操作按钮和溢出按钮。


操作栏为用户提供了访问与应用程序的当前环境中最重要的行动项目。那些带图标和/或文本直接出现在动作条被称为操作按钮。无法容纳在操作栏或不足够重要操作都隐藏在行动溢出。用户可以通过按压右侧的溢出按钮(或装置菜单按钮,如果有的话)揭示的其他动作的列表。


当你的活动启动时,系统通过调用您的活动的onCreateOptionsMenu()方法填充的行动项目。使用此方法可充气定义的所有操作项目??菜单资源。例如,这里有一个菜单资源定义了几个菜单项:

res/menu/main_activity_actions.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:id="@+id/action_search"          android:icon="@drawable/ic_action_search"          android:title="@string/action_search"/>    <item android:id="@+id/action_compose"          android:icon="@drawable/ic_action_compose"          android:title="@string/action_compose" /></menu>
然后在你的活动onCreateOptionsMenu()方法,填充菜单资源到给定的菜单到每个项目添加到操作栏:

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu items for use in the action bar    MenuInflater inflater = getMenuInflater();    inflater.inflate(R.menu.main_activity_actions, menu);    return super.onCreateOptionsMenu(menu);}
要申请一个项目操作栏中的操作按钮直接显示,包括在<item>标签showAsAction=“ifRoom”。 例如:

<menu xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >    <item android:id="@+id/action_search"          android:icon="@drawable/ic_action_search"          android:title="@string/action_search"          yourapp:showAsAction="ifRoom"  />    ...</menu>
如果没有足够的空间,在操作栏中的项目,它会出现在动作溢出。


使用XML的支持库属性
请注意,上述showAsAction属性使用在<menu>标签定义自定义命名空间。使用由支持库定义的任何XML属性的时候,因为在旧设备上的Android框架不存在这些属性,这是必要的。所以,你必须使用自己的名称空间作为由支持库中定义的所有属性的前缀。
如果你的菜单项,同时提供了一个标题和图标的标题和图标属性,那么行动项目仅显示默认的图标。如果你想显示的文字标题,添加“withText”到showAsAction属性。 例如:

<item yourapp:showAsAction="ifRoom|withText" ... />
注:“withText”值是一个提示文本标题应该出现在动作条。可能的情况下操作栏将显示标题,但可能不会,如果一个图标可用并且操作栏被约束的空间。


你应该总是定义标题为每个项目,即使你不申报的标题出现在操作项,原因如下:


如果没有足够的空间在操作项操作栏,菜单项出现在只有标题出现的溢出。
屏幕阅读器的视障用户阅读菜单项的标题。
如果操作的项目出现,只有图标,用户可以长按来揭示一个工具提示,显示操作标题的项目。
图标是可选的,但建议。对于图标设计建议,请参阅意象设计指南。您也可以下载一组从下载页面标准动作栏图标(如搜索或放弃)。


您还可以使用“总是”,宣布一个项目总是显示为一个操作按钮。但是,你不应该强迫一个项目以这种方式出现在动作条。这样做可以创建一个窄屏幕的设备布局问题。这是最好的,而不是用“ifRoom”来要求一个项目出现在动作条,但允许系统将其移动到溢出时,有没有足够的空间。然而,这可能是必要的,如果该项目包括不能被折叠,并且必须始终可见以提供进入一个关键特征的动作,以使用此值。


搬运行动项目点击


当用户按下一个动作时,系统调用您的活动的onOptionsItemSelected()方法。使用菜单项通过这种方法,可以通过调用getItemId标识操作()。这将返回由<项目>提供的唯一的ID标签的id属性,因此您可以执行相应的操作。例如:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    // Handle presses on the action bar items    switch (item.getItemId()) {        case R.id.action_search:            openSearch();            return true;        case R.id.action_compose:            composeMessage();            return true;        default:            return super.onOptionsItemSelected(item);    }}
注意:如果从一个片段膨胀的菜单项,通过碎片类的onCreateOptionsMenu()回调,系统调用onOptionsItemSelected()为片段,当用户选择这些项目中的一个。然而,活动都有机会第一处理该事件,因此,系统首先在活动呼叫onOptionsItemSelected(),要求该片段在同一回调之前。为了确保在活动的任何片段也有机会来处理回调,总是调用传递给超类的默认行为,而不是返回false时,你不处理的项目。


图3.实体模型显示制表符(左)的操作栏,然后拆分操作栏(中);与应用程序图标和标题禁用(右)。

使用拆分操作栏
拆分操作栏在屏幕的底部提供了一个独立的酒吧时显示活动的窄屏幕(如面向肖象的手机)上运行的所有行动项目。
分离行动项目这种方式保证了空间的合理数量可显示一个狭窄的屏幕上你所有的行动项目,同时留出空间在顶部导航和标题元素。
要使用支持库时启用拆分行动起来吧,你必须做两件事情:
添加uiOptions=“splitActionBarWhenNarrow”每个<活动>元素或<application>元素。此属性是API14级及更高版本(它是由旧版本忽略)只听懂。
为了支持旧版本中,添加<元数据>元素每个<活动>元素声明了“android.support.UI OPTIONS”同等价值的一个孩子。
例如:

<manifest ...>    <activity uiOptions="splitActionBarWhenNarrow" ... >        <meta-data android:name="android.support.UI_OPTIONS"                   android:value="splitActionBarWhenNarrow" />    </activity></manifest>
采用分体式操作栏也可以让导航选项卡崩溃到主操作栏,如果你删除的图标和标题(如图3所示右侧)。要产生这种效果,禁用操作栏图标和标题与setDisplayShowHomeEnabled(假)和setDisplayShowTitleEnabled(假)。


导航与应用程序图标


设计指南
导航与返回和向上


图4.在Gmail向上按钮。


启用应用程序图标为一个向上按钮允许用户根据屏幕之间的层次关系来浏览你的应用程序。例如,如果画面A显示的项目的列表,并选择项目导致屏幕B,则画面B应该包括向上按钮,返回到屏幕A.


注意:向上导航是从系统返回按钮提供的后退导航不同。后退按钮是用来通过屏幕上的用户最近使用过的历史以时间倒序浏览。它通常是基于屏幕之间的时间关系,而不是应用程序的分层结构(其是基础向上导航)。


为了使应用程序图标为一个向上按钮,呼叫setDisplayHomeAsUpEnabled()。例如

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_details);    ActionBar actionBar = getSupportActionBar();    actionBar.setDisplayHomeAsUpEnabled(true);    ...}
现在,在操作栏中的图标出现在向上插入符号(如图4所示)。然而,它不会做默认任何事情。指定活动在用户按下向上按钮打开,你有两个选择:


指定清单文件中的父活动。
这是最好的选择,当父活动总是相同的。通过在其活性父舱单申报,操作栏会自动执行,当用户按下向上按钮正确的行动。
在搭载Android 4.1(API级别16)开始,您可以在<活动>元素parentActivityName属性声明父。
为了支持支持库旧设备,还包括一个<元数据>元素指定为android.support.PARENT_ACTIVITY值父活动。 例如:

<application ... >    ...    <!-- The main/home activity (has no parent activity) -->    <activity        android:name="com.example.myfirstapp.MainActivity" ...>        ...    </activity>    <!-- A child of the main activity -->    <activity        android:name="com.example.myfirstapp.DisplayMessageActivity"        android:label="@string/title_activity_display_message"        android:parentActivityName="com.example.myfirstapp.MainActivity" >        <!-- Parent activity meta-data to support API level 7+ -->        <meta-data            android:name="android.support.PARENT_ACTIVITY"            android:value="com.example.myfirstapp.MainActivity" />    </activity></application>
一旦父活动在这样的清单中指定并启用与setDisplayHomeAsUpEnabled(向上按钮),你的工作就完成了,并在操作栏中正确导航了。
或者,在你的活动覆盖getSupportParentActivityIntent()和onCreateSupportNavigateUpTaskStack()。
这是在适当的时候根据用户如何到达当前屏幕中的父活动可以是不同的。也就是说,如果有用户可以采取到达当前屏幕许多路径,向上按钮应沿着路径用户实际跟随到那里向后导航。


系统调用getSupportParentActivityIntent()当用户按下向上按钮在导航您的应用程序(在应用自己的任务范围内)。如果这应该打开在了导航的活动的不同取决于用户如何到达当前位置,那么你应该重写此方法以返回启动相应的父活动的意图。


系统调用onCreateSupportNavigateUpTaskStack()为您的活动,当用户在你的活动是不属于你的应用程序正在运行的任务按下向上按钮。因此,你必须使用TaskStackBuilder传递给此方法来构造,当用户浏览了应合成相应的回堆栈。


即使你覆盖getSupportParentActivityIntent()当用户浏览您的应用程序指定最多的导航,你可以不用通过如上图所示,宣布在清单文件中“默认”父活动来实现onCreateSupportNavigateUpTaskStack()。然后onCreateSupportNavigateUpTaskStack()的默认实现将综合基于清单中声明父活动一回堆栈。


注意:如果您已经使用了一系列的片段而不是多个活动建立你的应用程序的层次结构,那么上述两个选项将工作。相反,通过您的片段向上导航,覆盖onSupportNavigateUp()被从后面堆栈弹出当前片段致电popBackStack交易通常执行适当的片段()。


有关实现向上导航的更多信息,请阅读提供高达导航。


增加一个动作视图




图5.带有可折叠搜索查看的行动吧。


一个动作的观点是出现在动作栏为操作按钮的替代一个小部件。一个动作视图提供在不改变活动或片段,而无需更换操作栏快速访问丰富的动作。例如,如果你有一个搜索行动,你可以添加一个动作视图嵌入了一个搜索查看窗口小部件在操作栏,如图5。


要声明一个动作视图,使用actionLayout或actionViewClass属性来指定一个布局资源或widget类分别使用。例如,这里是如何添加搜索查看窗口小部件

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >    <item android:id="@+id/action_search"          android:title="@string/action_search"          android:icon="@drawable/ic_action_search"          yourapp:showAsAction="ifRoom|collapseActionView"          yourapp:actionViewClass="android.support.v7.widget.SearchView" /></menu>
请注意,showAsAction属性还包括“collapseActionView”的价值。这是可选的,并宣布行动视图应该被折叠成一个按钮。 (此行为有关处理湿陷性行动享有以下部分进一步说明。)


如果您需要配置动作视图(如添加事件侦听器),可以在onCreateOptionsMenu()回调过程中这样做。您可以通过调用静态方法MenuItemCompat.getActionView(),并通过其相应的菜单项收购行动视图对象。例如,从上述样品的搜索小插件,获取这样的

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.main_activity_actions, menu);    MenuItem searchItem = menu.findItem(R.id.action_search);    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);    // Configure the search info and add any event listeners    ...    return super.onCreateOptionsMenu(menu);}
在API级别11或更高版本
通过对相应的MenuItem调用getActionView()获取行动的看法:

menu.findItem(R.id.action_search).getActionView()
有关使用搜索小插件的详细信息,请参阅创建一个搜索界面。


可折叠的处理意见行动


为了保持操作栏空间,您可以折叠的动作视图成一个操作按钮。折叠时,系统可能会放置行动统一到行动上溢,但是当用户选择它的动作看法仍然出现在动作条。您可以通过添加“collapseActionView”到showAsAction属性,如图上面的XML使您的操作视图可折叠。


因为系统,当用户选择的操作扩展动作视图,不需要在onOptionsItemSelected()回调的项目作出响应。该系统还调用onOptionsItemSelected(),但是如果你返回true(表示你已经处理,而不是事件),那么操作视图将无法展开。


当用户按下向上按钮或后退按钮系统也崩溃你的动作视图。


如果您需要更新根据你的行动视图的可见性的活动,您可以在动作通过定义OnActionExpandListener并将它传递给setOnActionExpandListener()展开和折叠接收回调。例如:

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.options, menu);    MenuItem menuItem = menu.findItem(R.id.actionItem);    ...    // When using the support library, the setOnActionExpandListener() method is    // static and accepts the MenuItem object as an argument    MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {        @Override        public boolean onMenuItemActionCollapse(MenuItem item) {            // Do something when collapsed            return true;  // Return true to collapse action view        }        @Override        public boolean onMenuItemActionExpand(MenuItem item) {            // Do something when expanded            return true;  // Return true to expand action view        }    });}
增加一个动作提供商




图6. ShareActionProvider一个操作栏展开,显示共享的目标。


类似的动作来看,一个动作提供商替换定制布局的操作按钮。然而,与一个动作来看,一个动作提供者承担所有的动作的行为的控制,并按下时的动作提供商可以显示一个子菜单。


要声明一个动作提供商,在菜单的<item>供应actionViewClass属性有一个完全合格的类名的ActionProvider标记。


您可以通过扩展ActionProvider类建立自己的操作提供,而Android提供了一些预建行动提供商如ShareActionProvider,这有利于通过展示直接操作栏中的共享成为可能的应用程序列表的“共享”的动作(如图所示在图6中)。


因为每个ActionProvider类定义了自己的动作行为,你并不需要听在onOptionsItemSelected()方法的动作。如果需要的话,虽然,你仍然可以听在onOptionsItemSelected()方法click事件的情况下,你需要同时执行其他操作。但一定要返回false,这样的动作仍然提供商接收onPerformDefaultAction()回调发挥其预期作用。


然而,如果动作提供商提供的动作的子菜单,那么你的活动不会当用户打开该列表或选择子菜单项中的一个接收到onOptionsItemSelected()的调用。


使用ShareActionProvider


要添加具有ShareActionProvider一个“共享”的动作,与ShareActionProvider类定义actionProviderClass一个<item>标签。例如:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >    <item android:id="@+id/action_share"          android:title="@string/share"          yourapp:showAsAction="ifRoom"          yourapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"          />    ...</menu>
现在的动作提供商采取的操作项目的控制,并可以处理它的外观和行为。但你还是必须提供当它出现在动作溢出用于该项目的标题。


剩下要做的唯一一件事是确定要使用共享的目的。要做到这一点,编辑onCreateOptionsMenu()方法调用MenuItemCompat.getActionProvider(),并通过它的菜单项抱着动作提供商。然后在返回ShareActionProvider调用setShareIntent(),并附加了相应的内容传递一个ACTION_SEND意图。


你应该onCreateOptionsMenu()中调用一次setShareIntent()来初始化份额的行动,但由于用户上下文可能会发生变化,则必须再次调用setShareIntent更新的意图随时可共享内容的变化()。


例如:

private ShareActionProvider mShareActionProvider;@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.main_activity_actions, menu);    // Set up ShareActionProvider's default share intent    MenuItem shareItem = menu.findItem(R.id.action_share);    mShareActionProvider = (ShareActionProvider)            MenuItemCompat.getActionProvider(shareItem);    mShareActionProvider.setShareIntent(getDefaultIntent());    return super.onCreateOptionsMenu(menu);}/** Defines a default (dummy) share intent to initialize the action provider.  * However, as soon as the actual content to be used in the intent  * is known or changes, you must update the share intent by again calling  * mShareActionProvider.setShareIntent()  */private Intent getDefaultIntent() {    Intent intent = new Intent(Intent.ACTION_SEND);    intent.setType("image/*");    return intent;}
该ShareActionProvider现在处理与该项目的所有用户交互和你不需要处理单击从onOptionsItemSelected()回调方法事件。
默认情况下,ShareActionProvider保留对每个共享目标的等级的基础上如何经常在用户选择各一个。更常用的份额目标出现在下拉列表的顶部和最常使用的目标直接显示在操作栏的默认共享的目标。默认情况下,排名信息被保存在默认情况下SHARE_HISTORY FILE_NAME指定名称的私人文件。如果使用ShareActionProvider或它的只有一个类型的行动的一个延伸,那么你应该继续使用这个默认的历史文件并没有什么,你需要做的。但是,如果使用ShareActionProvider或它与语义不同的含义多个动作的延伸,则每个ShareActionProvider应当以保持其自己的历史指定它自己的历史文件。以指定ShareActionProvider不同历史文件,调用setShareHistoryFileName(),并提供一个XML文件的名称(例如,“custom_share_history.xml”)。
注意:虽然根据使用频率的ShareActionProvider份额居的目标,行为是可扩展的,ShareActionProvider的扩展可以执行不同的行为和排名基于历史文件(如适用)。
创建一个自定义操作提供
创建你自己的行动提供商可以让您重新利用和管理动态操作项行为一个独立的模块中,而不是处理行动项目转化和行为在你的片段或活动代码。正如上一节中显示,Android版已经提供了份额的行为ActionProvider的执行情况:ShareActionProvider。
要创建一个不同的动作你自己的行动提供商,只需扩展ActionProvider类并实现其回调方法为宜。最重要的是,你应该实现以下几点:
ActionProvider()
此构造函数传递你的应用程序上下文,你应??该在成员字段保存在其他的回调方法使用。
onCreateActionView(菜单项)
这是你定义该项目的动作视图。使用从构造函数来实例化一个LayoutInflater,并从一个XML资源抬高你的动作视图布局收购了上下文,然后勾事件侦听器。例如

public View onCreateActionView(MenuItem forItem) {    // 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()
当从动作溢出选择菜单项和行动提供者应该对菜单项的默认操作的系统调用这一点。
但是,如果你的行动提供商提供了一个子菜单,通过onPrepareSubMenu()回调,然后在子菜单出现,即使动作提供商放置在行动溢出。对此,onPerformDefaultAction()时,有一个子不会被调用。
注意:一个活动或实现onOptionsItemSelected(一片段)可以覆盖动作提供商的默认行为(除非它使用一个子菜单)通过处理所选择的项目事件(和返回真),在这种情况下,系统不调用onPerformDefaultAction( )。
对于行动提供的一个例子延伸,看动作条SettingsActionProviderActivity。
添加导航选项卡


图7.宽屏幕上操作栏标签。


设计指南
标签
另请参阅
创建具有选项卡刷卡次数


图狭窄的屏幕上8标签。


操作栏中的标签很容易让用户探索,并在您的应用程序不同的视图之间切换。因为他们适应不同屏幕尺寸的动作条提供的标??签是理想的。例如,当屏幕是足够宽的标签显示在操作栏旁边的操作按钮(例如,当在一个片剂,在图7中示出),而当一个窄屏幕上它们出现在一个独立的杆(称为“堆栈操作栏”,如图8所示)。在某些情况下,Android系统将改为显示您的选项卡项目作为一个下拉列表,以确保操作栏中的最佳选择。


要开始,你的布局必须包含在其中放置一个标签相关联的每个片段的ViewGroup。请确保ViewGroup中有一个资源的ID,这样你可以从你的代码中引用它,并在它交换标签。


一旦你确定了片段出现在布局上,基本步骤添加的标签是:


实施ActionBar.TabListener接口。该接口提供回调选项卡上的事件,当用户按下一个,这样你可以换标签等。
对于要添加的每个选项卡,实例化一个ActionBar.Tab并通过调用setTabListener设置ActionBar.TabListener()。还设置选项卡的标题和的setText()(以及可选的setIcon用一个图标())。
然后通过调用addTab添加每个选项卡来操作栏()。
注意,ActionBar.TabListener回调方法不指定该片段与所述标签相关联的,而仅仅是其中ActionBar.Tab被选中。你必须定义每个ActionBar.Tab,它代表了相应片段之间你自己的关联。有几种方法可以定义的关联,这取决于你的设计。


例如,这里是你如何实现的ActionBar.TabListener使得每个标签使用自己的监听器实例:

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {    private Fragment mFragment;    private final Activity mActivity;    private final String mTag;    private final Class<T> mClass;    /** Constructor used each time a new tab is created.      * @param activity  The host Activity, used to instantiate the fragment      * @param tag  The identifier tag for the fragment      * @param clz  The fragment's Class, used to instantiate the fragment      */    public TabListener(Activity activity, String tag, Class<T> clz) {        mActivity = activity;        mTag = tag;        mClass = clz;    }    /* The following are each of the ActionBar.TabListener callbacks */    public void onTabSelected(Tab tab, FragmentTransaction ft) {        // Check if the fragment is already initialized        if (mFragment == null) {            // If not, instantiate and add it to the activity            mFragment = Fragment.instantiate(mActivity, mClass.getName());            ft.add(android.R.id.content, mFragment, mTag);        } else {            // If it exists, simply attach it in order to show it            ft.attach(mFragment);        }    }    public void onTabUnselected(Tab tab, FragmentTransaction ft) {        if (mFragment != null) {            // Detach the fragment, because another one is being attached            ft.detach(mFragment);        }    }    public void onTabReselected(Tab tab, FragmentTransaction ft) {        // User selected the already selected tab. Usually do nothing.    }}
标签
另请参阅
创建具有选项卡刷卡次数


图狭窄的屏幕上8标签。


操作栏中的标签很容易让用户探索,并在您的应用程序不同的视图之间切换。因为他们适应不同屏幕尺寸的动作条提供的标??签是理想的。例如,当屏幕足够宽的标签出现在操作栏旁边的操作按钮(例如,当在平板电脑上,如图7所示),注意:你不能调用commit()的片段交易在每这些回调,该系统为您调用它,如果你自己叫它它可??能会抛出异常。你也不能添加这些片段交易到后面堆栈。


在这个例子中,收听者简单地固定(附着())的活性的片段布局或如果不是实例化,创建片段并添加(添加())它的布局(如android.R.id的子 - 当相应的选项卡中选择.content视图组),并分离(分离()),它当标签处于未选中状态。


剩下的工作就是创建的每个ActionBar.Tab并将其添加到动作条。此外,您必须调用setNavigationMode(NAVIGATION_MODE_TABS),以使标签可见。


例如,下面的代码添加使用以上定义的侦听两个标签:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // Notice that setContentView() is not used, because we use the root    // android.R.id.content as the container for each fragment    // setup action bar for tabs    ActionBar actionBar = getSupportActionBar();    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);    actionBar.setDisplayShowTitleEnabled(false);    Tab tab = actionBar.newTab()                       .setText(R.string.artist)                       .setTabListener(new TabListener<ArtistFragment>(                               this, "artist", ArtistFragment.class));    actionBar.addTab(tab);    tab = actionBar.newTab()                   .setText(R.string.album)                   .setTabListener(new TabListener<AlbumFragment>(                           this, "album", AlbumFragment.class));    actionBar.addTab(tab);}
如果你的活动停止后,您应保留与保存的实例状态当前选择的选项卡,因此您可以在用户返回打开相应的选项卡。当它的时间来保存状态,您可以查询与setSelectedNavigationIndex当前选定的选项卡()。这将返回选定的选项卡的索引位置。
注意:您保存的每个片段的状态,这样当用户切换片段的标签,然后返回到前一个片段,它看起来他们离开时,它做的方式是很重要的。一些国家在默认情况下保存,但您可能需要手动保存状态为自定义的视图。有关保存片段的状态信息,请参阅碎片API指南。
注意:ActionBar.TabListener上面实施的几种可能的技术中的一种。另一种流行的选择是使用ViewPager管理片段,用户还可以使用滑动手势来切换标签。在这种情况下,你只需告诉ViewPager在onTabSelected()回调当前选项卡的位置。欲了解更多信息,请阅读创建带有选项卡刷卡次数。
添加下拉导航
图9.操作栏中的下拉导航列表。
至于你的活动导航(或过滤)的另一种模式,操作栏提供了一个内置的下拉列表(也称为“微调”)。例如,下拉式列表可以提供由在活动的内容进行排序不同的模式。
使用下拉列表时,改变的内容是重要的,但不一定是经常发生是非常有用的。在情况下,切换内容更加频繁,你应该使用导航选项卡来代替。
其基本过程启用下拉导航:
创建一个SpinnerAdapter提供可选项目的下拉并在列表绘制的每个项目时要使用的布局的列表。
实施ActionBar.OnNavigationListener定义当用户从列表中选择一个项目时发生的行为。
在您的活动的onCreate()方法,能够通过调用setNavigationMode(NAVIGATION_MODE_LIST)操作栏的下拉列表。
设置回调与setListNavigationCallbacks的下拉列表()。例如:

actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
此方法需要您SpinnerAdapter和ActionBar.OnNavigationListener。
此过程是相当短的,但实施SpinnerAdapter和ActionBar.OnNavigationListener是大多数的工作就完成了。有很多方法可以实现这些定义你的下拉导航和实施各类SpinnerAdapter的超出了本文档(你应该参考SpinnerAdapter类参考了解更多信息)的范围功能。不过,下面是一个SpinnerAdapter和ActionBar.OnNavigationListener让你开始(点击标题揭示样品)的例子。


  例如SpinnerAdapter和OnNavigationListener


样式化操作栏


如果你想实现一个可视化的设计,代表你的应用的品牌,操作栏,您可以自定义其外观的每一个细节,包括操作栏的颜色,文本颜色,按钮样式等。要做到这一点,你需要使用Android的风格和主题框架restyle采用特殊样式属性的操作栏。


注意:对于所有的背景可绘制你提供,请务必使用九宫格可绘制允许伸展。九片图像应该比40dp高大宽30dp较小。


总体外观


actionBarStyle
指定定义了操作栏的各种样式属性的样式资源。
这种风格此默认为Widget.AppCompat.ActionBar,这是你应父样式使用什么。


支持的类型包括:


background
定义操作栏背景绘制资源。
backgroundStacked
定义堆叠操作栏(标签)的可绘制资源。
backgroundSplit
定义拆分操作栏的可绘制资源。
actionButtonStyle
定义操作按钮的样式资源。
这种风格此默认为Widget.AppCompat.ActionButton,这是你应父样式使用什么。


actionOverflowButtonStyle
定义溢出行动项目的样式资源。
这种风格此默认为Widget.AppCompat.ActionButton.Overflow,这是你应父样式使用什么。


displayOptions
定义一个或多个操作栏显示选项,比如是否使用应用程序的标识,表明该活动的标题,或启用后续行动。看到所有可能的值displayOptions。
divider
定义操作项之间的分隔的可绘制资源。
titleTextStyle
定义操作栏标题样式资源。
这种风格此默认为TextAppearance.AppCompat.Widget.ActionBar.Title,这是你应父样式使用什么。


windowActionBarOverlay
声明的动作条是否应该覆盖的活动布局,而不是抵消活动的布局位置(例如,库应用程序使用覆盖模式)。这是默认为false。
通常情况下,行动起来吧,需要在屏幕上自己的空间和你的活动布局在什么遗留下来罢了。当动作条处于覆盖模式,你的活动布局使用所有可用空间,系统借鉴了顶部的操作栏。如果你希望你的内容保持在固定的大小和位置时的动作栏隐藏和显示叠加模式可能是有用的。你可能还喜欢单纯使用它作为一种视觉效果,因为你可以使用半透明背景的操作栏,因此用户仍然可以看到一些动作栏后面你的活动布局。


注:全息主题家庭绘制默认为半透明背景的操作栏。但是,你可以用你自己的风格进行修改,并在不同设备上DeviceDefault主题可能会默认使用不透明背景。


当启用覆盖模式,你的活动布局没有操作栏趴在它上面的意识。所以,你必须小心,不要放置任何重要的信息或UI组件由操作栏中覆盖的区域。如果合适的话,你可以参考平台的价值actionBarSize确定操作栏的高度,在你的XML布局引用它。例如:

<SomeView    ...    android:layout_marginTop="?android:attr/actionBarSize" />
您也可以在运行时使用的getHeight检索操作栏高度()。这反映了当时的操作栏,它被称为,这可能不包括堆叠操作栏(由于导航选项卡)如果在早期活动的生命周期方法调用的高度。就看你如何确定在运行时的总高度,包括堆叠操作栏,看到蜂窝库示例应用程序的标题片段类。
行动项目
actionButtonStyle
定义操作项按钮的样式资源。
这种风格此默认为Widget.AppCompat.ActionButton,这是你应父样式使用什么。
actionBarItemBackground
定义每个动作项目的背景绘制资源。这应该是一个国家的列表绘制来表示不同的选定状态。
itemBackground
定义每个动作溢出项的背景绘制资源。这应该是一个国家的列表绘制来表示不同的选定状态。
actionBarDivider
定义操作项之间的分隔的可绘制资源。
actionMenuTextColor
定义文字颜色出现在一个行动项目。
actionMenuTextAppearance
定义文本样式的资源,出现在一个行动项目。
actionBarWidgetTheme
定义被夸大到操作栏的动作看法部件主题资源。
导航标签
actionBarTabStyle
定义操作栏中的选项卡的样式资源。
这种风格此默认为Widget.AppCompat.ActionBar.TabView,这是你应父样式使用什么。
actionBarTabBarStyle
定义出现下面的导航选项卡中的细杆样式的资源。
这种风格此默认为Widget.AppCompat.ActionBar.TabBar,这是你应父样式使用什么。
actionBarTabTextStyle
定义导航标签文本的样式资源。
这种风格此默认为Widget.AppCompat.ActionBar.TabText,这是你应父样式使用什么。
下拉列表
actionDropDownStyle
定义样式下拉导航(如背景和文本样式)。
这种风格此默认为Widget.AppCompat.Spinner.DropDown.ActionBar,这是你应父样式使用什么。
例如主题
下面是定义一个自定义主题活动,CustomActivityTheme,包括几种风格来定制操作栏的例子。
请注意,有两个版本,每个动作条样式属性。第一个包括机器人:在属性名的前缀,支持API级别11和更高的,包括在框架中这些属性。第二个版本不包括机器人:前缀,是旧版本的平台,对其中的系统使用支持库样式属性的。针对每个效果是相同的。

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- the theme applied to the application or activity -->    <style name="CustomActionBarTheme"           parent="@style/Theme.AppCompat.Light">        <item name="android:actionBarStyle">@style/MyActionBar</item>        <item name="android:actionBarTabTextStyle">@style/TabTextStyle</item>        <item name="android:actionMenuTextColor">@color/actionbar_text</item>        <!-- Support library compatibility -->        <item name="actionBarStyle">@style/MyActionBar</item>        <item name="actionBarTabTextStyle">@style/TabTextStyle</item>        <item name="actionMenuTextColor">@color/actionbar_text</item>    </style>    <!-- general styles for the action bar -->    <style name="MyActionBar"           parent="@style/Widget.AppCompat.ActionBar">        <item name="android:titleTextStyle">@style/TitleTextStyle</item>        <item name="android:background">@drawable/actionbar_background</item>        <item name="android:backgroundStacked">@drawable/actionbar_background</item>        <item name="android:backgroundSplit">@drawable/actionbar_background</item>        <!-- Support library compatibility -->        <item name="titleTextStyle">@style/TitleTextStyle</item>        <item name="background">@drawable/actionbar_background</item>        <item name="backgroundStacked">@drawable/actionbar_background</item>        <item name="backgroundSplit">@drawable/actionbar_background</item>    </style>    <!-- action bar title text -->    <style name="TitleTextStyle"           parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">        <item name="android:textColor">@color/actionbar_text</item>    </style>    <!-- action bar tab text -->    <style name="TabTextStyle"           parent="@style/Widget.AppCompat.ActionBar.TabText">        <item name="android:textColor">@color/actionbar_text</item>    </style></resources>
在您的清单文件,您可以应用主题,您的整个应用程序:

<application android:theme="@style/CustomActionBarTheme" ... />
或个别活动:

<activity android:theme="@style/CustomActionBarTheme" ... />
注意:一定每个主题和风格声明在<style>标签,从它继承你的主题没有明确宣布所有样式父主题。当修改操作栏,使用父主题,这样你可以简单地覆盖你想改变,而无需重新实现你想独自离开(如文本大小或行动项目填充)样式的操作栏的样式是很重要的。
有关在应用程序中使用的风格和主题资源的更多信息,请阅读样式和主题。

  相关解决方案