为Android应用增加操作栏
操作栏是一个可以在你应用中实现的重要设计元素,它提供了多种接口方便你的应用和其它程序的交互。
主要功能包括:
1、 一个专门标识应用程序的空间;
2、 快速地执行重要的操作(比如搜索);
3、 支持切换窗口不同视图的导航栏(抽屉式)。
本次课程将讲述操作栏的基本属性。
设置操作栏
在很多应用中,操作栏左侧会显示应用的标题和图标。即使在一个简单的应用中,操作栏都是一个非常有用的元素,因为它标示着你的应用。
你需要通过将你的应用主题设置为支持操作栏之后,才能够在应用中设置操作栏。如何设置主题取决于你应用所支持的最低API版本,所以本课程将根据不同API版本分两部分来讲解操作栏。
仅支持Android 3.0及以上的版本
从Android 3.0起,开发者通过设置应用主题为Theme.Holo就可以在应用的所有窗口中包含操作栏。当targetSdkVersion或者minSdkVersion设置为11及以上版本时,它是应用的默认主题。
所以为了能够在你的应用中使用操作栏,最简单的方法是将你的应用支持最低的sdk版本设置为11或者更大,比如:
<manifest ... >
<uses-sdk android:minSdkVersion="11" ... />
...
</manifest>
注意:如果你是自定义的主题,你需要将Theme.Holo作为父主题才能正常地使用操作栏。
通过上面对应用主题的设置,你的应用就可以支持操作栏功能啦。
支持Android 2.1及以上的版本
如果想在Android 3.0之前版本使用功能栏,你需要在你的工程中加入依赖工程V7。
一旦你引入了这个依赖工程:
1、 将你窗口的继承关系改为继承ActionBarActivity,比如:
public class MainActivity extends ActionBarActivity { ... }
2、 同时在清单文件中你还要将你应用或者窗口的主题改为Theme.AppCompat,比如:
<activity android:theme="@style/Theme.AppCompat.Light" ... >
注意:如果你是自定义的主题,确保它的父主题是Theme.AppCompat才能正常使用操作栏。
现在你的程序就可以支持操作栏啦。
记得正确设置你的API版本:
<manifest ... >
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="18" />
...
</manifest>
添加操作按钮
操作栏允许你加上按钮来触发应用中最重要的功能,通常他们都是以图标或者带文本的按钮来展现的,通常会将不重要或者不适合在操作栏显示的视图隐藏。
上图中显示了一个搜索按钮和一个省略号按钮,点击省略号按钮就可展示被操作栏隐藏的视图啦。
在xml文件中配置操作栏
操作栏上布局可以通过xml菜单资源来进行配置,为了实现通过xml文件来配置操作栏,你需要在”res/men/”文件夹下创建一个针对操作栏布局的xml文件。
通过<item>标签将需要显示在操作栏的视图加进来,比如:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Search, should appear as action button -->
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom" />
<!-- Settings, should always be in the overflow -->
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:showAsAction="never" />
</menu>
当操作栏上的空间可用时,搜索操作将以一个操作按钮的的形式出现,但设置操作是在点击省略号后才会显示的(默认情况下,所有的操作都是在点击省略号后才会出现在展开的下拉列表里)。
“icon”属性指定的是一个图片资源,”@drawable/”后面的图片资源名称必须是在”res/drawable/”文件夹下已经存在的,比如:”@drawable/ic_action_search”就是指定”ic_action_search.png”作为其图标,而”title”指定的一个定义在”res/values/”目录下某个xml文件里的字符串。
注意:当你为你的应用创建一个图标或者其它图片资源时,你应该为相应资源指定多个版本来满足不同设备分辨率不同的情况。
如果你的应用API版本在2.1以下并且用到了依赖库文件,”android:showAcAction”将不会起作用。你应该通过以你自己指定的命名空间作为前缀来指定这个属性(自定义的xml命名空间最好是以你的应用名称,但是你也可以为其指定其它名称),比如:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
yourapp:showAsAction="ifRoom" />
...
</menu>
在操作栏上加入操作
为了在操作栏上加入菜单项,需要在你定义的activity类中实现onCreateOptionsMenu()回调来将需要添加的菜单项布局到窗口中,比如:
@Override
public 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);
}
响应操作按钮
当用户点击操作栏上的某一个按钮时,系统会回调activity的onOptionsItemSelected()方法,在这个回调方法里,通过MenuItem的getItemId()方法来获取当前点击操作按钮的ID(这个id是在上面xml文件的<item>标签下通过”android:id”属性来指定的):
@Override
public 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);
}
}
为非主界面窗口添加Up按钮
你应用中所有非主界面窗口都是通过操作栏上的up按钮返回上一个界面的。
当你使用的是Android 4.1(API 16)甚至更新时,又或者是你使用了依赖库中的ActionBarActivity,你只需要在清单文件中为窗口指定parent属性就可以使用up操作了。
比如,下面的示例就是教你如何在清单文件中为窗口定义parent属性的:
<application ... >
...
<!-- The main/home activity (it 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 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
在代码中通过调用setDisplayHomeAsUpEnabled()可以将应用图标作为up按钮:
@Override
public 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);
}
通过在清单文件中对窗口的parent属性定义后,系统可以知道DisplayMessageActivity的父窗口是MainActivity了。当用户点击Up按钮的时候,系统会直接跳转到其父窗口(你不需要对Up做任何响应)。
为操作栏设置风格
操作栏提供了一个书写的方式来执行操作和浏览你的程序,但是并不意味着在所有的程序中它的视觉效果都是一样的。你可以通过android的风格和主题资源轻松地让操作栏的视觉效果和你的产品更搭配。
Android内置了一些”dark”或者”light”的操作栏风格,你可以通过扩展这些主题来自定义你的操作栏。
注意:如果你是通过依赖包使用的操作栏,你必须使用Theme.AppCompat家族的风格(Theme.Holo家族只有在API 11及以上才可以使用)。所以,每个你自定义的风格属性都必须被定义两次:一个用于平台风格属性(在标签”android:”中使用),另一个用于依赖包的风格属性(在appcompat.R.attr中使用),详情请见下面的例程。
使用Android主题
Android包含两个指定操作栏颜色的主题:
1、”dark”风格的”Theme.Holo”;
2、“light”风格的”Theme.Holo.Light”。
你可以通过在清单文件中以”android:theme”属性在整个应用或者单个窗口定义来使用这些主题。
例如:
<application android:theme="@android:style/Theme.Holo.Light" ... />
在为整个应用使用上面这个主题时,你还可以单独为每个窗口指定其他主题。
当使用依赖库的时候,你就不能使用上述的那些主题了,你要使用Theme.AppCompat家族的主题:
1、”dark”主题的”Theme.AppCompat”;
2、”light”主题的”Theme.AppCompat.Light”;
3、黑色操作栏搭配亮色主题”Theme.AppCompat.Light.DarkActionBar”。
请确保你使用的操作栏图标和当前主题是否搭配,为了帮助你做到这一点,”Action Bar Icon Pack”针对不同的操作栏主题包含了对应的操作栏图标。
自定义操作栏背景
为了改变操作栏的背景,你需要通过复写actionBarStyle属性来为你的窗口操作栏自定义一个主题。
如果你的应用使用的是”navigation tabs”或者是”split actionbar”,你仍然可以通过backgroundStacked和backgroundSplit属性来为操作栏指定背景。
Android3.0及以上的版本
如果你的应用只支持Android 3.0及以上的版本,你可以这样来定义操作栏的背景:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/MyActionBar</item>
</style>
<!-- ActionBar styles -->
<style name="MyActionBar"
parent="@style/Widget.Holo.Light.ActionBar.Solid.Inverse">
<item name="android:background">@drawable/actionbar_background</item>
</style>
</resources>
然后将该主题应用于整个应用或者单个窗口:
<application android:theme="@style/CustomActionBarTheme" ... />
Android2.1及以上版本
当使用的是依赖库并且想达到上面相同的操作栏显示效果时,你需要像下面这样定义主题:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/MyActionBar</item>
</style>
<!-- ActionBar styles -->
<style name="MyActionBar"
parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="android:background">@drawable/actionbar_background</item>
<!-- Support library compatibility -->
<item name="background">@drawable/actionbar_background</item>
</style>
</resources>
然后将该主题应用于整个应用或者单个窗口:
<application android:theme="@style/CustomActionBarTheme" ... />
自定义文本颜色
为了修改操作栏的文本颜色,你需要为每个文本自定义颜色。
1、 操作栏标题:为actionBarStyle自定义一个风格,为其指定textColor属性和titleTextStyle风格。
2、 操作栏表格:在窗口主题中复写”actionBarTabTextStyle”属性;
3、 操作栏按钮:在窗口主题中复写”actionMenuTextColor”属性。
Android3.0及以上版本
如果你的应用只支持Android 3.0及以上的版本,你自定主题的xml文件类似于下面这样:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<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>
<!-- ActionBar styles -->
<style name="MyActionBar"
parent="@style/Widget.Holo.ActionBar">
<item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
</style>
<!-- ActionBar title text -->
<style name="MyActionBarTitleText"
parent="@style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">@color/actionbar_text</item>
</style>
<!-- ActionBar tabs text styles -->
<style name="MyActionBarTabText"
parent="@style/Widget.Holo.ActionBar.TabText">
<item name="android:textColor">@color/actionbar_text</item>
</style>
</resources>
Android2.1及以上版本
当你使用了依赖库,你在xml文件中自定义的主题看起来是这个样子的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<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>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/MyActionBar</item>
<item name="actionBarTabTextStyle">@style/MyActionBarTabText</item>
<item name="actionMenuTextColor">@color/actionbar_text</item>
</style>
<!-- ActionBar styles -->
<style name="MyActionBar"
parent="@style/Widget.AppCompat.ActionBar">
<item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
<!-- Support library compatibility -->
<item name="titleTextStyle">@style/MyActionBarTitleText</item>
</style>
<!-- ActionBar title text -->
<style name="MyActionBarTitleText"
parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">@color/actionbar_text</item>
<!-- The textColor property is backward compatible with the Support Library -->
</style>
<!-- ActionBar tabs text -->
<style name="MyActionBarTabText"
parent="@style/Widget.AppCompat.ActionBar.TabText">
<item name="android:textColor">@color/actionbar_text</item>
<!-- The textColor property is backward compatible with the Support Library -->
</style>
</resources>
自定义表指示器
想要修改导航栏表项的指示器,你需要自定义窗口主题并复写其actionBarTabStyle。
比如:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- STATES WHEN BUTTON IS NOT PRESSED -->
<!-- Non focused states -->
<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" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<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" />
<!-- STATES WHEN BUTTON IS PRESSED -->
<!-- Non focused states -->
<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" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<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>
Android3.0及以上版本
如果你的应用只支持Android 3.0及以上版本,你应用的主题文件看起来应该是这样的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.Holo">
<item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
</style>
<!-- ActionBar tabs styles -->
<style name="MyActionBarTabs"
parent="@style/Widget.Holo.ActionBar.TabView">
<!-- tab indicator -->
<item name="android:background">@drawable/actionbar_tab_indicator</item>
</style>
</resources>
Android2.1及以上版本
如果你使用了依赖库,在Android 2.1及以上版本中你的主题文件看起来是这样的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.AppCompat">
<item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
<!-- Support library compatibility -->
<item name="actionBarTabStyle">@style/MyActionBarTabs</item>
</style>
<!-- ActionBar tabs styles -->
<style name="MyActionBarTabs"
parent="@style/Widget.AppCompat.ActionBar.TabView">
<!-- tab indicator -->
<item name="android:background">@drawable/actionbar_tab_indicator</item>
<!-- Support library compatibility -->
<item name="background">@drawable/actionbar_tab_indicator</item>
</style>
</resources>
覆盖操作栏
默认情况下,操作栏是显示在窗口的顶部的,明显的减少了你窗口的布局空间。加入,在本课程的交流中,有人需要人为地控制操作栏的显示或者隐藏。你可以调用ActionBar的hide()和show()方法来达到这种效果。然而,在隐藏和显示操作栏的过程中会导致你的窗口需要重画和重新布局。
为了避免在隐藏和显示操作的过程中存在拉伸窗口布局的情况,你可以使能操作栏的overlay模式,当使用overlay模式时,操作栏将置于窗口布局的最上层,你可以使用整个窗口的空间,就和没有操作栏一样一样的,通过定义操作栏的显示模式,就不需要在操作栏显示或者隐藏时对窗口布局进行拉伸了。
小提示:如果你需要使你窗口被操作栏遮住的地方部分可见,你可以自定义一个透明的操作栏的主题。
使能覆盖模式
为了使能操作栏的覆盖模式,你需要通过复写已经存在的操作栏主题的”android:windowActionBarOverlay”为”true”这种自定义操作栏的方式来使能其覆盖模式。
Android 3.0及以上的版本
如果你的应用只支持Android 3.1及以上的版本,你自定义的主题应该使用”Theme.Holo”作为父主题,比如:
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@android:style/Theme.Holo">
<item name="android:windowActionBarOverlay">true</item>
</style>
</resources>
Android2.1及以上版本
如果你的应用支持Android 2.1以上,Android 3.0以下的版本,你自定义的主题必须要一”Theme.AppCompat”作为其父主题,比如:
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@android:style/Theme.AppCompat">
<item name="android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="windowActionBarOverlay">true</item>
</style>
</resources>
为布局指定Top-margin属性
如果操作栏为overlay模式,为了能够让被actionbar遮住的窗口布局处于持续可见,你需要做如下处理:
<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>
如果你是通过依赖库使用的操作栏,你需要将以paddingTop的android:前缀移除:
<!-- Support library compatibility -->
<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”适用于所有版本的Android应用。
原文链接:Adding the Action Bar