码迷,mamicode.com
首页 > 其他好文 > 详细

Action Bar

时间:2016-07-05 10:23:13      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

简介

action bar 是一个功能窗口,用于标识应用程序和用户的位置,并提供给用户一些操作和导航模式。你应该在大多数需要提供用户操作或导航的activities 时使用它。因为action bar 为用户在不同的屏幕上提供了一致的界面,并且它优雅的适应类不同的系统外观。你可以通过使用ActionBar 类来控制action bar 。
Action Bar 的主要目标:
  1. 提供一个专有的空间用于显示应用程序的标识或用户的位置
  2. 在不同的application上提供一致的导航和细化视图
  3. 突出显示一些关键的活动(例如查找、分享),并且能够实现它们的功能
技术分享
从左到又依次为:logo(1)、导航选项卡(2)、任务项目(3)

添加action bar

从安卓3.0(V11)开始,action bar就已经包含在了Theme.Holo 这类主题之中。该主题为targetSdkVersion="11"或之上的默认主题
如果你想使用action bar 的API,例如增加导航模式或者自定义样式,应该设置android:minSdkVersion="11"或之上。

移除action bar

如果你在一个activity中不需要 action bar 设置它的主题为.NoActionBar,或者调用action bar的hide()方法进行隐藏,当然,show()方法可以再显示出来。
注意由于action bar的移除或隐藏而带来的布局空间的变化。如果你的activity经常性的进行action bar的隐藏/显示,你或许应该使用叠加模式(overlay mode)进行布局。
将你的action bar 放在最上层布局中,这样action bar的显隐便不会影响你的布局。
使用叠加模式,为你的activity创建一个主题且设置android:windowActionBarOverlay=true,更多信息请查看。

添加action items(活动项)

有时候你需要在选项菜单中给用户一些直接的选项,为了实现它,必须在action bar中声明这些菜单项(menu item)并作为活动项。
一个活动项包含一个icon和text title,如果一个菜单项没有作为活动项显示,那么系统会将它放在溢出菜单(overflow menu)中。
当activitty第一次启动,系统通过调用onCreateOptionsMenu()填充action bar 和溢出菜单。
在这个回调方法中,你应该增加一个XML文件用以定义菜单项的菜单资源。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity, menu);
return true;
}

在这个xml文件中,你可以设置一个菜单项作为活动项通过<item>元素中的声明:android:showAsAction="ifRoom" 这样,只有当有足够空间时才会直接显示在action bar上,否则会被收入溢出菜单。
设置显示的图标和文字:android:title 、 android:icon 但安卓只会默认的显示icon。如果需要显示文字,必须在android:showAsAction中加上withText。可能由于空间问题文字显示不全。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_save"
android:icon="@drawable/ic_menu_save"
android:title="@string/menu_save"
android:showAsAction="ifRoom|withText" />
</menu>


当用户选中了某一个活动项,activity recive便会调用onOptionsItemSelected()
为每个菜单项定义他的title是十分有必要的,尽管他不会总是显示出来:
  • 当没有足够空间显示该活动项时,它便会收入溢出菜单,而在溢出菜单中显示的是它的title
  • 有时屏幕受损的用户需要阅读title而不是icon 
  • 如果活动项仅仅显示icon,用户可以长按按钮来显示这个item的title
icon项是可选的,但也是推荐有的。
如果你在fragement中添加菜单项,要确保onOptionsItemSelected()先于fragement内的回调函数。
你也可以声明一个项目总是(always)作为活动项显示,而不是收入溢出菜单。当空间受限时,就不该使用always这个值。最好使用ifRoom。

选则活动项

你应该谨慎的选择那些直接显示出来的菜单项作为活动项,一般,每一个活动项至少遵循一种如下情况:
  • 频繁使用:十次有七次都会使用的操作
  • 重要:它提供的功能能够简便用户的操作。
  • 典型的:在类似的app中都会提供的操作,例如刷新,新建等。
如果你有超过4个菜单项需要作为活动项,那么你必须谨慎的考虑他们的相对等级,并且努力不要超过4个活动项(使用ifRoom是个好办法),即使有足够的空间也不应该显示太多的活动项。
另外,如下的操作都不应该作为活动项显示:设置、帮助、反馈或者类似的。
如果有需要,查找操作应该是你显示的第一个活动项

使用分离操作栏(split action bar)

这是一个专门为狭窄屏幕手机设计的action bar,它的导航部分(2)和app声明部分(1)是分离的。
使用它必须在manifest文件中的<application>或<activity>中加上uiOptions="splitActionBarWhenNarrow"。
尽管在4.0才出现的,但在之前的版本也能工作 

使用app 图标进行导航

默认情况下,你的app图标会显示在action bar的左边,如果需要,可以将它作为一个活动项。一般会做如下两件事情:
  • 回到应用的主activity
  • Navigating up
当用户触摸icon 系统便会调用activity里的 onOptionsItemSelected() 方法,并且传递android.R.id.home ID。作为响应,应该启动主actiivty或者返回上一个activity。
如果是返回主activity,应该在intent中设置flag=FLAG_ACTIVITY_CLEAR_TOP有了这个flag,它会销毁在主activity之前的所有activity,以确保主activity在第一个(栈顶)。
下面是一个点击icon返回主activity的片段
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
为确保用户能够通过其它app进入当前的activity,也可能需要加上 FLAG_ACTIVITY_NEW_TASK flag。事实上,当你的app需要接受来自其他app的intent,都需要加入该flag。
在4.0及其之后的版本,你必须调用setHomeButtonEnabled(true) 指定icon作为一个活动项。

Navigating up

up 不同于back ,有时候会另启一个新的任务栈,从而不能使用返回键返回上一屏幕状态。
使用该功能,必须调用action bar的setDisplayHomeAsUpEnabled(true) 函数,其它设置同上。

使用action view

action view 是作为action item按钮的替代项而显示在action bar上的小部件。
技术分享
在你的菜单资源文件中声明一个action view 需含有 android:actionLayout 或者android:actionViewClass属性
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="ifRoom|collapseActionView"//表明需要嵌入一个button中,当用户点击该按钮,view展开。
android:actionViewClass="android.widget.SearchView" />
</menu>
如果需要添加一些事件钩子,可以在onCreateOptionsMenu()中通过如下示例获得实例对象:
@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);
}

action view 的折叠处理

一般系统会自动处理扩展和折叠,你不必做任何操作,只需要像上面item这样配置即可。
一般对查找功能的action view的操作,建议使用SearchView. 这个类。当然,一些设备也会提供专有的查找按钮,使用时只需在onKeyUp() 监听 KEYCODE_SEARCH 事件,然后调用expandActionView().
你可以在展开或折叠后做一些事情,通过设置监听器:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options, menu);
MenuItem menuItem = menu.findItem(R.id.actionItem);
...
 
menuItem.setOnActionExpandListener(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
}
});
}

使用action provider

详情请跳转至Action Provider

使用导航选项卡(Navigation Tabs)

在选项卡之间切换的本质是使用FragmentTransaction切换fragement,如果不熟悉fragement的切换,请看延伸阅读关于fragemnt部分。
使用一个view group包含每一个fragement的tab,并确保view group有一个id以便于在你的切换代码中引用它。

一旦你决定类如何显示你的fragement,将它加入tab需要如下基本几步:
  1. Implement  ActionBar.TabListener 
  2. 对于每个你想加入的tab 实例化一个 ActionBar.Tab and 通过调用setTabListener()设置 ActionBar.TabListener . 也还要设置tab的title/icon 通过 setText() / setIcon().
  3. 通过调用 addTab().将每一个tab加入action bar。

关于tabListener,下面一段示例展示了一个标准的fragement转换规则:
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.
}
}

这个片段展示类如何显示tab,它使用了上面的Listener:
@Override
protected 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 = getActionBar();
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);
}

如果你的app停止运行了,你必须保存现有的选择状态。调用getSelectedNavigationIndex()获得当前选中的选项卡的index。

使用下拉的导航(drop-down Navigation 

基本步骤如下:
  1. 创建一个SpinnerAdapter 用于提供下拉的选项和布局
  2. Implement ActionBar.OnNavigationListener 
  3. 为action bar 启用导航模式:actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
  4. 设置回调:actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
下面几段代码展示了简单的使用:
步骤1:
SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.action_list,
android.R.layout.simple_spinner_dropdown_item);
<?xml version="1.0" encoding="utf-8"?>
<!---数组文件--->
<resources>
<string-array name="action_list">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
</string-array>
</pre>
步骤2:
mOnNavigationListener = new OnNavigationListener() {
// Get the same strings provided for the drop-down‘s ArrayAdapter
String[] strings = getResources().getStringArray(R.array.action_list);
 
@Override
public boolean onNavigationItemSelected(int position, long itemId) {
// Create new fragment from our own Fragment class
ListContentFragment newFragment = new ListContentFragment();
FragmentTransaction ft = openFragmentTransaction();
// Replace whatever is in the fragment container with this fragment
// and give the fragment a tag name equal to the string at the position selected
ft.replace(R.id.fragment_container, newFragment, strings[position]);
// Apply changes
ft.commit();
return true;
}
};

action bar的样式

如果你想在你的应用中使用自定义小部件,那么也应该重新设计action bar使之匹配你的风格设计。为此,你需要使用安卓的样式和主题框架。
选择图片匹配不同状态下的控件(例如按钮的按下、弹起、选择),使用xml文件的selector。
你提供所有背景图片,使用.9png格式具有更好的延展性。.9png格式的图片高不超过40px宽不超过30px
普通外观
声明action bar是覆盖整个activity layout 而不是根据layout进行偏移,(例如 画廊应用Gallery app就是使用此样式)它的默认值是false。
通常,action bar需要自己的空间,然后你的布局再填充剩下的空间。当使用 覆盖模式(overlay mode)时,布局会使用所有可用的空间,然后action bar 绘制在屏幕的顶部。
当你的内容大小和位置是固定的时候,覆盖模式实现action bar的显示/隐藏时会有很好的效果。
也可以使用一个半透明的背景,这样在action bar的下面仍然可以看到一些内容。
注意:Hole主题会默认的半透明的绘制action bar,你可以用自定义的样式来修改它。在DeviceDefault 主题下默认的绘制是不透明的。
当覆盖模式启用时,你的layout并不会意识到有action bat在顶部。因此,必须注意在action bar覆盖的部分不能放置重要信息或者ui组件。如果合适的话,可以引用平台的actionBarSize确定action bar的高度。在xml布局文件中引用这个值
<SomeView
...
android:layout_marginTop="?android:attr/actionBarSize" />
还可以使用getHeight().获得action bar的高度,如果在activity生命周期的早期调用这个方法,那么调用时返回的高度并不包括堆叠操作栏(因为导航标签)。要看如何在运行时判断操作栏总的高度(包括被堆放的操作栏),请看Honeycomb Gallery示例应用中的TitlesFragment类。

action items

android:actionButtonStyle
为按钮定义一个样式资源
android:actionBarItemBackground
为每个action item定义一个背景资源 (Added in API level 14.)
android:itemBackground
为每个 溢出菜单中的item定义背景资源
android:actionBarDivider
在action item之间(即分割线)指定图片资源 (Added in API level 14.)
android:actionMenuTextColor
action item显示文本的颜色
android:actionMenuTextAppearance
 action item显示文本的样式
android:actionBarWidgetTheme
给作为操作视窗被填充到操作栏中的可视构件定义主题资源(Added in API level 14.)

Navigation tabs

android:actionBarTabStyle
给操作栏中的选项标签定义样式资源。
android:actionBarTabBarStyle
给显示在导航选项标签下方的细条定义样式资源。
android:actionBarTabTextStyle
给导航选项标签中的文本定义样式资源。

Drop-down lists

android:actionDropDownStyle
给下拉列表定义样式资源。
下面的片段展示了给一个action bar 定义的一些样式
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
<item name="android:actionBarTabTextStyle">@style/CustomTabTextStyle</item>
<item name="android:actionBarDivider">@drawable/ab_divider</item>
<item name="android:actionBarItemBackground">@drawable/ab_item_background</item>
</style>
 
<!-- style for the action bar tab text -->
<style name="CustomTabTextStyle" parent="@android:style/TextAppearance.Holo">
<item name="android:textColor">#2456c2</item>
</style>
</resources>
注意:你的每一个<style> 标签都必须有一个父主题。这样当一些样式你没有指定的时候会使用父主题的样式。
在整个应用或activitys中使用你的样式:<application android:theme="@style/CustomActivityTheme" ... />

高级样式

如果需要使用比上述更高级的样式,在你的主题中包含android:actionBarStyle and android:actionBarSplitStyle 可以定义action bar的各种属性,包括 android:backgroundandroid:backgroundSplit, and android:backgroundStacked. 的不同背景。同样,确保有个父主题。
下面是一个示例改变操作栏背景
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<!-- other activity and action bar styles here -->
</style>
 
<!-- style for the action bar backgrounds -->
<style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
<item name="android:background">@drawable/ab_background</item>
<item name="android:backgroundStacked">@drawable/ab_background</item>
<item name="android:backgroundSplit">@drawable/ab_split_background</item>
</style>
</resources>


延伸阅读

了解更多关于上下文操作栏的信息:http://android-doc.com/guide/topics/ui/menus.html#context-menu
关于Search 接口/查找功能的实现:http://android-doc.com/guide/topics/search/search-dialog.html

Action Bar

标签:

原文地址:http://blog.csdn.net/yh_android_blog/article/details/51828488

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!