Adding an Action Provider
Similar to an action view, an action provider replaces an action button with a customized layout. However, unlike an action view, an action provider takes control of all the action's behaviors and an action provider can display a submenu when pressed.
Figure 6. An action bar withShareActionProvider
expanded to show share targets.
To declare an action provider, supply the actionViewClass
attribute in the menu <item>
tag with a fully-qualified class name for an ActionProvider
.
You can build your own action provider by extending the ActionProvider
class, but Android provides some pre-built action providers such as ShareActionProvider
, which facilitates a "share" action by showing a list of possible apps for sharing directly in the action bar (as shown in figure 6).
Because each ActionProvider
class defines its own action behaviors, you don't need to listen for the action in the onOptionsItemSelected()
method. If necessary though, you can still listen for the click event in the onOptionsItemSelected()
method in case you need to simultaneously perform another action. But be sure to return false
so that the the action provider still receives the onPerformDefaultAction()
callback to perform its intended action.
However, if the action provider provides a submenu of actions, then your activity does not receive a call to onOptionsItemSelected()
when the user opens the list or selects one of the submenu items.
Using the ShareActionProvider
To add a "share" action with ShareActionProvider
, define the actionProviderClass
for an <item>
tag with the ShareActionProvider
class. For example:
使用ShareActionProvider第1步,在menu.xml中声明某个item的属性为 android:actionProviderClass="xxx.ShareActionProvider"
<?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>
Now the action provider takes control of the action item and handles both its appearance and behavior. But you must still provide a title for the item to be used when it appears in the action overflow.
The only thing left to do is define the Intent
you want to use for sharing. To do so, edit your onCreateOptionsMenu()
method to call MenuItemCompat.getActionProvider()
and pass it the MenuItem
holding the action provider. Then call setShareIntent()
on the returned ShareActionProvider
and pass it an ACTION_SEND
intent with the appropriate content attached.
You should call setShareIntent()
once during onCreateOptionsMenu()
to initialize the share action, but because the user context might change, you must update the intent any time the shareable content changes by again calling setShareIntent()
.
使用ShareActionProvider第2步,在代码中找到在menu中声明支持ActionPorivder的操作项,在代码中设置共享类型.
For example:
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; }
The ShareActionProvider
now handles all user interaction with the item and you do not need to handle click events from the onOptionsItemSelected()
callback method.
By default, the ShareActionProvider
retains a ranking for each share target based on how often the user selects each one. The share targets used more frequently appear at the top of the drop-down list and the target used most often appears directly in the action bar as the default share target. By default, the ranking information is saved in a private file with a name specified by DEFAULT_SHARE_HISTORY_FILE_NAME
. If you use the ShareActionProvider
or an extension of it for only one type of action, then you should continue to use this default history file and there's nothing you need to do. However, if you use ShareActionProvider
or an extension of it for multiple actions with semantically different meanings, then each ShareActionProvider
should specify its own history file in order to maintain its own history. To specify a different history file for the ShareActionProvider
, call setShareHistoryFileName()
and provide an XML file name (for example,"custom_share_history.xml"
).
Note: Although the ShareActionProvider ranks share targets based on frequency of use, the behavior is extensible and extensions of ShareActionProvider can perform different behaviors and ranking based on the history file (if appropriate).
Creating a custom action provider
Creating your own action provider allows you to re-use and manage dynamic action item behaviors in a self-contained module, rather than handle action item transformations and behaviors in your fragment or activity code. As shown in the previous section, Android already provides an implementation of ActionProvider
for share actions: the ShareActionProvider
.
To create your own action provider for a different action, simply extend the ActionProvider
class and implement its callback methods as appropriate. Most importantly, you should implement the following:
自定义ActionProvider要继承ActionProvider类,相关接口如下,定义一个接口后,再像前面那样在menu,xml中指定某个item为这个新定义的ActionProvider子类就可.
ActionProvider()
-
Context
, which you should save in a member field to use in the other callback methods. onCreateActionView(MenuItem)
-
Context
acquired from the constructor to instantiate aLayoutInflater
and inflate your action view layout from an XML resource, then hook up event listeners. For example: -
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()
-
- However, if your action provider provides a submenu, through the
onPrepareSubMenu()
callback, then the submenu appears even when the action provider is placed in the action overflow. Thus,onPerformDefaultAction()
is never called when there is a submenu.
Note: An activity or a fragment that implements onOptionsItemSelected()
can override the action provider's default behavior (unless it uses a submenu) by handling the item-selected event (and returningtrue
), in which case, the system does not call onPerformDefaultAction()
.
For an example extension of ActionProvider
, see ActionBarSettingsActionProviderActivity.