Android训练课程(Android Training) - 添加活动栏(使用action bar)

96
张云飞Vir
2016.06.22 17:50* 字数 4896

添加活动栏(Adding the Action Bar)

活动栏action bar 是非常重要的设计元素之一,你可以为你的app中的activity来实现它。它提供了数个用户界面特性,这些特性使得你的app立即让用户觉得亲和,它再不同的安卓app中提供了一致性。关键功能包括:
为你的app提供标识的一个专用的区域 ,并且在app中指示用户的当前位置。
以一种可预言的方式访问重要的活动(比如搜索)
支持导航和视图切换(通过标签或者下拉列表实现)


这节训练课程提供了一个关于action bar 基础的快速指南。关于actionbar 的各种特性的更多信息,请参阅 Action Bar 指南。

课程

设置action bar
学习如何添加一个基础的action bar到你的activity,不论你的app仅仅支持安卓3.0及其以上 或者也支持和安卓2.1一样的版本(通过使用安卓支持库 Android Support Library)
添加活动按钮
学习如何再action bar上 添加并且对用户活动作出响应。
样式化你的action bar
学习如何自定义你的action bar的呈现样子
漂浮action bar
学习如何如何再你的布局前面覆盖action bar,允许当你隐藏action bar时可以无缝转换。


2014-10-28 张云飞 翻译自:https://developer.android.com/training/basics/actionbar/setting-up.html
设置action bar
在它的大多数基本形式中,action bar 为activity显示一个标题和再左侧显示一个app图标。即使是这个简单的形式,action bar 对于所有的activity来说仍然是有用的,它告知了用户他们在哪里,和为app维持一个一致的标识。


表1. 一个具有app图标和activity标题的简单action bar.

设置一个基本的action bar 需要你的app使用一个启用了action bar 的 主题。如何去请求一个这样的主题,取决于 你的app的最低支持版本。那么这节课按照你的最低支持的安卓版本来分成两个章节。

仅支持安卓3.0以上
从安卓3.0(API级别11),action bar被包含在所有使用了Theme.Holo主题(或者它的后代继承者之一)的activity内,当 targetSdkVersion
或者 minSdkVersion 属性被设置为
"11"
以及更大的时候,它将是默认的样式。
那么,添加action bar 到你的activity,很简单的设置这个属性为11或者更高。比如下面这样:
<manifest ... > <uses-sdk android:minSdkVersion="11" ... /> ...</manifest>

注意: 如果你创建了一个自定义的主题,确保它使用了 一个Theme.Holo主题来作为它的父主题。更多详细,请阅读 Styling the Action Bar.
现在Theme.Holo主题被应用到你的应用,并且所有的activity都展示了action bar。就是这样。

支持安卓2.1以上
当运行在比安卓3.0更早期的版本时(向下直到2.1版本),要添加action bar,需要在你的应用程序里包含安卓支持库(Android Support Library)。

在开始,阅读 Support Library Setup 文档,并设置 v7 appcompat 库(一旦你下载了库的包,跟随 使用资源添加库 Adding libraries with resources 的说明)。
一旦你在你的app项目中集成了安卓支持库Support Library。

  1. 更新你的activity让它继承自 ActionBarActivity
    . 比如:
    public class MainActivity extends ActionBarActivity { ... }

  2. 在你的 清单文件manifest中, 更新 <application>
    元素或者 单独的 <activity>
    元素 使用一个 Theme.AppCompat
    主题,比如:
    <activity android:theme="@style/Theme.AppCompat.Light" ... >

注意: 如果你创建了一个自定义的主题,确保它使用了 一个Theme.Holo主题来作为它的父主题。更多详细,请阅读 Styling the Action Bar.
现在你的activity包含了actionbar,当它运行在安卓2.1(API 级别7)或者更高。
记住在清单文件manifest中,适当设置你的 app支持的API级别:
<manifest ... > <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="18" /> ...</manifest>

下一课:添加action按钮。NEXT: ADDING ACTION BUTTONS

2014-10-29 张云飞 翻译自: https://developer.android.com/training/basics/actionbar/adding-buttons.html
添加Action按钮 (Adding Action Buttons)
action bar 允许你为 关联到app的当前上下文的那些 活动项(action items)添加按钮。大家已知的action按钮 指的是 那些 直接在action bar中显示一个图标 和/或 文字活动,那些不能填充 在actionbar的 或者 不够重要的 被隐藏在action的溢出部分
(译者注:我们能看到的图标的或者文字的就是按钮action button了,不可见就是隐藏的扩展按钮action overflow)


图一. 一个action bar包含了一个用于搜索的action按钮和action溢出部分,它展示了扩展按钮。

在XML中指定活动(Specify the Actions in XML)
所有的action按钮 和其他在扩展按钮中的可用的项(action overflow)都被定义在一个XML 菜单资源 menu resource.中。为了在action bar中添加 action,在你的项目的 res/menu/
文件夹下 创建一个XML文件。
为你想要包含在action中的每一项,添加<item>元素,比如:
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" android:showAsAction="ifRoom" /> <item android:id="@+id/action_settings" android:title="@string/action_settings" android:showAsAction="never" /></menu>

在这个声明里搜索活动在action bar上有足够空间时将会显示成action按钮的样子,但是设置活动总是出现在备选(扩展)按钮里。(默认情况下,所有的action都出现在备选按钮的形式,但是明确地为每个 action活动声明你的设计目的是个很好的实践。)

icon属性需要指定一个图片的资源ID。跟随在 @drawable/后面的名字 必须是一个你保存在你的项目下的res/drawable/目录下的图片的名字。比如"@drawable/ic_action_search"
引用到 ic_action_search.png 这个文件。同样的,title
属性使用一个字符串资源,这个字符串资源已经在你项目中的 res/values/目录下的一个XML文件中被定义过。更多的讨论请阅读Building a Simple User Interface.

注意: 当你在你的app中创建一个图标或者其他位图图像时,为不同的屏幕密度 提供各自优化的多版本 是非常重要的。更多讨论请阅读 Supporting Different Screens.
如果你为了兼容像安卓2.1这样的版本,而使用了支持库Support Library,showAsAction 属性在android: 命名空间里是不可用的。代替这个属性方法由Support Library提供,你必须定义你自己的XML命名空间,和使用那个命名空间作为属性前缀。(一个自定义的命名空间应该以你的app的名称作为基础)。但是,它可以是任意的你想定义的名称,和仅仅在这个文件的周期中是可以用的。比如:
res/menu/main_activity_actions.xml
<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>

下载Action bar 图标
为了最好的匹配安卓 iconography 指南,你应该使用在 Action Bar Icon Pack中提供的图标。

添加活动到action bar 中
要放置菜单项到action bar总,实现你的activity中的 onCreateOptionsMenu()
回调方法,填充(inflate)菜单资源到指定的Menu对象中,比如:
@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);}

对按钮做出反应
当用户点击一个action bar中的action 按钮或者扩展按钮时,系统就调用你的activity的 onOptionsItemSelected()
回调方法。在你的这个方法的实现中,调用给出的Menuitem的 getItemId()方法以决定哪一个item被点击了,这个方法返回的ID匹配一个值,这值是你已经在相应的<item>元素中的android: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_settings: openSettings(); return true; default: return super.onOptionsItemSelected(item); }}

为低级别的activity添加向上(Up) 按钮



你的app中的所有的屏幕中,那些不是主入口的(不是Home屏幕的activity) 都应该为用户提供一种方式以导航到 在app的层级关系中是逻辑上的父屏幕 ,这可以通过点击action bar 上的 Up按钮方式。

当运行在安卓4.1(API级别16)或者更高,或者当在支持库中使用ActionBarActivity
时,处理Up导航都是很简单的需要你在manifest文件中声明父activity和为action bar 启用Up按钮。

例如,这里是在manifest文件中你如何声明一个activity的父activity。
<application ... > ... <activity android:name="com.example.myfirstapp.MainActivity" ...> ... </activity> <activity android:name="com.example.myfirstapp.DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity></application>

这时,通过调用 setDisplayHomeAsUpEnabled()
启用app图标作为Up按钮:
@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_displaymessage); getSupportActionBar().setDisplayHomeAsUpEnabled(true); // If your minSdkVersion is 11 or higher, instead use: // getActionBar().setDisplayHomeAsUpEnabled(true);}

因为系统已经自动 DisplayMessageActivity 的 父activity 是
MainActivity
,这时点击 Up 按钮, 系统导航到相应的父activity —你不需要处理 Up 按钮的事件.
关于 up 按钮的更多信息 请阅读 Providing Up Navigation.

下一课:样式化你的action bar NEXT: STYLING THE ACTION BAR


2014-10-29 张云飞VIR翻译自:https://developer.android.com/training/basics/actionbar/styling.html
样式化你的action bar
action bar 向你的用户提供了一个熟悉的和可预言的方式去处理活动action和导航你的app,但是这并不意味者它要精确的看起来和其他app一样。如果你想要样式化你的action bar,更好的适应你的产品品牌,你可以很容易的利用 样式和主题 style and theme 资源.来达成。
安卓包含了一些内置的activity 主题,其中有深色的“dart",和浅色的”light" action bar 的风格。你可以继承这些主题来进一步自定义你的actionbar 的样子。
注意:如果你为actionbar 使用了Support Library 的API,这时你必须 使用(或者重载override)Theme.AppCompat 家族系主题(相当于于 Theme.Holo
族系,在API级别11或者更高下可用)。在这样做,每个你声明的风格属性必须被声明两次:一次是平台的样式属性(使用android:属性),和一次使用在Support Library中包含的样式属性(使用appcompat.R.attr属性-那些属性的上下文是实际的)。下面的示例有更多详细。

使用一个安卓主题
安卓为action bar包含了两个指示颜色的基准线主题:
Theme.Holo 是一个深色(黑色)主题。
Theme.Holo.Light 浅色(白色,亮色)主题。


你可以应用这些主题到你的整个app或者单个activity,通过在manifest文件中使用android:theme属性作用于<application>元素,或者单个<activity>元素。
例如:
<application android:theme="@android:style/Theme.Holo.Light" ... />

你也可以通过声明 Theme.Holo.Light.DarkActionBar
的方式,使用一个深色的actionbar,同时剩余的全部activity使用浅色的方案。

当你使用Support Library 时,你必须使用 Theme.AppCompat
主题来代替:
Theme.AppCompat
深色主题.
Theme.AppCompat.Light
浅色主题.
Theme.AppCompat.Light.DarkActionBar
浅色主题但是action bar 是深色的.

确保你使用 恰当的与你的action bar 的颜色形成对比色 的action bar 图标。为了帮助你,action bar图标包( Action Bar Icon Pack )为Holocaust light和 Holo dark 这两个action bar 而包含了标准的action图标。

自定义背景


要修改action bar 的背景,为你的activity创建一个自定义的覆盖(重载)了actionBarStyle
属性的主题。这个属性指向一个其他的样式,在这个样式里你可以覆盖 background 属性为action bar 去指定一个可绘制的资源。

如果你的app使用了 导航标签 navigation tabs 或者 分离的action bar( split action bar),这时你也可以使用backgroundStacked
and backgroundSplit
为那些 “栏” 分别指定背景。
警告: 从你的自定义主题 声明一个合适的父主题并且你的样式继承那些样式 是重要的。如果没有一个父主题,你的action bar 将会失去 很多 样式属性,直到你自己明确的声明它们。

仅支持安卓3.0或者更高的平台
当仅支持安卓3.0或者更高的平台时,你可以定义action bar 的背景像下面这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar"> <item name="android:actionBarStyle">@style/MyActionBar</item> </style> <style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:background">@drawable/actionbar_background</item> </style></resources>

这时,应用你的主题到整个app或者单个activity:
<application android:theme="@style/CustomActionBarTheme" ... />

支持安卓2.1及以上
当使用 Support Library,和上面一样的样式必须被替换成这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar"> <item name="android:actionBarStyle">@style/MyActionBar</item> <item name="actionBarStyle">@style/MyActionBar</item> </style> <style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse"> <item name="android:background">@drawable/actionbar_background</item> <item name="background">@drawable/actionbar_background</item> </style></resources>

这时,应用你的主题到整个app或者单个activity:
<application android:theme="@style/CustomActionBarTheme" ... />

自定义文本颜色
要修改在actionbar 里的文本的颜色,你需要为每个文本元素覆盖各自独立的属性。
action bar 标题:创建一个指定了 textColor 属性的自定义的样式,并且在你自定义的actionStyle里通过 titleTextStyle
属性 指定指示这个样式。注意: 被应用到 titleTextStyle 的自定义属性应该 使用
TextAppearance.Holo.Widget.ActionBar.Title 作为父样式。

action bar 选项卡(tabs): 在你的activity样式里 覆盖 actionBarTabTextStyle

action 按钮:在你的activity样式里 覆盖actionMenuTextColor

仅支持安卓3.0及以上
当仅支持安卓3.0及以上,你的样式XML文件可以像这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyActionBar</item> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> <item name="android:actionMenuTextColor">@color/actionbar_text</item> </style> <style name="MyActionBar" parent="@style/Widget.Holo.ActionBar"> <item name="android:titleTextStyle">@style/MyActionBarTitleText</item> </style> <style name="MyActionBarTitleText" parent="@style/TextAppearance.Holo.Widget.ActionBar.Title"> <item name="android:textColor">@color/actionbar_text</item> </style> <style name="MyActionBarTabText" parent="@style/Widget.Holo.ActionBar.TabText"> <item name="android:textColor">@color/actionbar_text</item> </style></resources>

仅支持安卓2.1及以上
当使用Support Library,你的样式XML文件可以像这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@style/Theme.AppCompat"> <item name="android:actionBarStyle">@style/MyActionBar</item> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> <item name="android:actionMenuTextColor">@color/actionbar_text</item> <item name="actionBarStyle">@style/MyActionBar</item> <item name="actionBarTabTextStyle">@style/MyActionBarTabText</item> <item name="actionMenuTextColor">@color/actionbar_text</item> </style> <style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar"> <item name="android:titleTextStyle">@style/MyActionBarTitleText</item> <item name="titleTextStyle">@style/MyActionBarTitleText</item> </style> <style name="MyActionBarTitleText" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"> <item name="android:textColor">@color/actionbar_text</item> </style> <style name="MyActionBarTabText" parent="@style/Widget.AppCompat.ActionBar.TabText"> <item name="android:textColor">@color/actionbar_text</item> </style></resources>

自定义选项卡(标签,tab)指示器


要更改被用于 导航标签navigation tabs 的指示器,就创建一个 覆盖了actionBarTabStyle 属性的activity主题。这个属性指向 另外一个你覆盖了background
属性的 样式资源,它应该指定一个 状态列表特性的绘制对象(drawable)。
注意: 状态列表特性的绘制对象(drawable)是很重要的,当前选中状态的标签的背景是和其他不同的。更多关于如何创建一个drawable资源处理多种按钮状体的信息,请阅读 State List 文档。
例如,下面是一个 状态列表特性的drawable,它声明了一个指定的背景图片适应不同的action bar 标签的状态。
res/drawable/actionbar_tab_indicator.xml

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected" /> <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected" /> <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused" /> <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused" /> <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed" /> <item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed" /> <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed" /> <item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed" /></selector>

仅支持安卓3.0及以上
当仅支持安卓3.0及以上,你的样式XML文件可以像这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@style/Theme.Holo"> <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> </style> <style name="MyActionBarTabs" parent="@style/Widget.Holo.ActionBar.TabView"> <item name="android:background">@drawable/actionbar_tab_indicator</item> </style></resources>

仅支持安卓2.1及以上
当使用Support Library,你的样式XML文件可以像这样:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?><resources> <style name="CustomActionBarTheme" parent="@style/Theme.AppCompat"> <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> <item name="actionBarTabStyle">@style/MyActionBarTabs</item> </style> <style name="MyActionBarTabs" parent="@style/Widget.AppCompat.ActionBar.TabView"> <item name="android:background">@drawable/actionbar_tab_indicator</item> <item name="background">@drawable/actionbar_tab_indicator</item> </style></resources>

更多资源
看更多 action bar 的样式属性,在 Action Bar 指南中被列出的.
在 样式和主题Styles and Themes 指南中学习如何使用样式.【译者注:我另一篇文章里翻译了这个章节】
要 action bar 的更多完整的样式, 尝试阅读 安卓actionbar样式生成器 Android Action Bar Style Generator.

下一课:漂浮actionbar NEXT: OVERLAYING THE ACTION BAR

2014-10-29 张云飞 翻译自: https://developer.android.com/training/basics/actionbar/overlaying.html
漂浮actionbar
默认情况下,action bar出现在你的activity窗口的顶部,对于activity布局的剩余空间来说,稍微减少一定数量的可用空间。假设,在和用户交互的过程中,你想要隐藏和显示actionbar,你可以通过在actionbar中的hide()和show()方法来这样做。然而,这将会导致你的activity去基于它的新尺寸重新计算和绘制基本的布局。
当action bar隐藏或者展示时,去避免你的布局改变大小,你可以为action bar 启用 漂浮模式。当在漂浮模式时,你的activity布局使用了所有的可用空间,就像action bar不在那里一样,并且系统在你的布局前面 绘制了 actionbar。这使得在顶部的一些布局显得模糊,但是现在当action bar隐藏或者出现时,系统都不需要重新为你的布局改变尺寸而且是无缝的改变。
提示: 如果你希望你的布局在action bar 后面 部分可见,为action bar创建一个部分透明的背景的自定义样式。像 图一 展示的这样。更多信息关于如何定义action bar 的背景,参考上文Styling the Action Bar


图一

启用漂浮模式
为action bar 开启漂浮模式,你需要去创建一个自定义的主题,该主题继承自一个已经存在的action bar 主题,并且设置 android:windowActionBarOverlay 属性为 true。
仅支持安卓3.0及以上
如果你的 minSdkVersion
设置为11或者更高,你的自定义主题应该使用 Theme.Holo主题(或者一个它的后代)作为父主题。例如:
<resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:windowActionBarOverlay">true</item> </style></resources>

支持安卓2.1及以上
如果你的app使用了Support Library 为了兼容性以运行在版本低于安卓3.0的设备上,你的自定义主题可以使用 Theme.AppCompat主题(或者一个它的后代)作为你的父主题。例如:
<resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.AppCompat"> <item name="android:windowActionBarOverlay">true</item> <item name="windowActionBarOverlay">true</item> </style></resources>

另外要注意,这个样式对于 windowActionBarOverlay
包含了两种定义: 一个具有Android:前缀,一个没有。一个具有Android:前缀是支持包含了平台样式的安卓版本 ,另一个没有前缀的是支持较旧的从Support Library中读取的版本。

指定布局的顶部空白(Top-margin)
当action bar 在漂浮模式时,它可能使一些你的仍然可见的布局模糊。要确保这样的项在所有时间都保持在actionbar 下面,通过 actionBarSize 使用 指定的高度 为视图的顶部 添加 外边距margin 或者 内边距padding 两者之一。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="?android:attr/actionBarSize"> ...</RelativeLayout>

如果你使用了 Support Library ,你需要去删除 Android: 前缀,例如:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="?attr/actionBarSize"> ...</RelativeLayout>

在这样的情况下, ?attr/actionBarSize 值没有前缀,它可以工作在所有的版本,包括安卓3.0以及更高。

Android