Action视图是一个在ActionBar上作为Action Button 的替代品。要声明一个视图,需要使用 actionLayout 和 actionViewClass 两个属性中的任意一个来分别定义视图的布局资源和布局类。
下面介绍如何定义 Searview 组件:
<?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>
Note:showAsAction属性中也包含 collapseActionView ,这是可选择的值,声明视图被收缩成一个按钮。
如果想配置视图(比如添加事件监听),你可以在 onCreateOptionsMenu() 函数中做这些事情。如果你想获取视图对象可以使用静态方法 MenuItemCompat.getActionView()
@Override public 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 或者更高
获取视图对象使用 getActionView()函数
menu.findItem(R.id.action_search).getActionView()
更多的信息关于搜索部件看 Creating a Search Interface。
处理可折叠的Action视图
为了保护Action Bar的空间,你需要将你的视图收缩成一个按钮,这时候你就需要为视图添加一个 collapseActionView值给 showAsAction属性,如上所述。
当用户选择视图时,系统会将视图伸展开,你不需要回应这一项在OnOptionsItemSelected() 函数中。如果你想更新你的Activity基于你的可见的视图,当视图收缩和伸展时你可以接受回调函数。
@Override public 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 } }); }
和 action view 类似,action provider 也是用一个自定义的布局替代action button。然而并不完全像 action view ,action provider 控制了所有的action的行为,并且当按下后 action provider可以弹出子菜单。
为了什么action provider,需要在menu中的<item>标签用一个ActionProvider的完全限定类的类名提供 actionViewClass 属性。
你可以创建你自己的acion provider 通过继承ActionProvider类。由于ActionProvider定义了自己的行为,所以不需要再 onOptionsItemSelected()方法中添加监听,如果需要你仍然可以在onOptionsItemSelected()中设置监听,以防你需要同时执行其他的action,但是仍然要返回false,以便action provider 还可以 接受onPerformDefaultAction()回调函数去执行它的意图action。
ShareActionProvider
使用 ShareActionProvider 添加加一个“share”action。
<?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>
现在 action provider可以控制它的选项和处理它的显示和动作,但是你必须要为选项提供一个标题。剩下唯一要做的事情就是为分享定义一个Intent。这样做,你就要编辑onCreateOptionsMenu
方法调用
MenuItemCompat.getActionProvider() 和当按下
MenuItem 时的处理。然后使用返回的ShareActionProvider的 setShareIntent() 方法,并且传递给它一个有合适的附加内容的ACTION_SEND意图。
你要在onCreateOptionMuenu()初始化 share action 时调用setShareIntent() ,这是因为用户的环境可能会变化,你必须随时更新意图,通过再一次调用setShareIntent() 可以分享的内容会发生变化。
private ShareActionProvider mShareActionProvider; @Override public 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; }
自定义 action provider
创建一个你自己的 action provider 允许你可以再次使用和管理动态的action item,Android 早已经提供了一种实现方式,通过继承 ActionProvider 类和实现它的回调函数,重要的有以下两个:
ActionProvider()
这个构造器传递给你的应用程序上下文,你应该保存这个在一个成员变量里,以后可以使用在其他的回调函数中。
onCreateActionView(MenuItem)
在这里定义视图,从构造器里使用 Context
获取实例化 LayoutInflater
和 从XML资源中inflate 你的视图布局,然后绑定事件监听。
一旦你确定了fragment在布局文件中出现的位置,下面是添加标签的基本步骤:
Implement the ActionBar.TabListener
interface. This interface provides callbacks for tab events, such as when the user presses one so you can swap the tabs.
For each tab you want to add, instantiate an ActionBar.Tab
and set the ActionBar.TabListener
by calling setTabListener()
. Also set the tab's title and with setText()
(and optionally, an icon with setIcon()
).
Then add each tab to the action bar by calling addTab()
.
/** 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 *//* The following are each of the callbacks */// Check if the fragment is already initialized// If not, instantiate and add it to the activity// If it exists, simply attach it in order to show it// Detach the fragment, because another one is being attached// User selected the already selected tab. Usually do nothing.
// 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
下面是添加 drop-down Navigation的基本步骤
Create a SpinnerAdapter
that provides the list of selectable items for the drop-down and the layout to use when drawing each item in the list.
Implement ActionBar.OnNavigationListener
to define the behavior that occurs when the user selects an item from the list.
During your activity's onCreate()
method, enable the action bar's drop-down list by callingsetNavigationMode(NAVIGATION_MODE_LIST)
.
Set the callback for the drop-down list with setListNavigationCallbacks()
. For example:
actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
This method takes your SpinnerAdapter
and ActionBar.OnNavigationListener
.