【发布时间】:2012-05-22 16:57:18
【问题描述】:
Android 4.0 中提供的新 ShareActionProvider(如果您使用的是 ActionBarSherlock,则在更早的版本中)具有一项功能,即最后使用的项目显示在操作栏中。有什么办法可以关掉吗?
【问题讨论】:
标签: android android-actionbar actionbarsherlock shareactionprovider
Android 4.0 中提供的新 ShareActionProvider(如果您使用的是 ActionBarSherlock,则在更早的版本中)具有一项功能,即最后使用的项目显示在操作栏中。有什么办法可以关掉吗?
【问题讨论】:
标签: android android-actionbar actionbarsherlock shareactionprovider
对我来说,避免历史图标的最佳解决方案是不要使用 ShareActionProvider,而是将其创建为任何其他操作:
<item
android:id="@+id/menu_action_share"
android:showAsAction="ifRoom"
android:icon="@drawable/ic_action_share"
android:title="@string/share"/>
在 menu/activity_actions.xml 中放置一个带有 ic_action_share 图标的项目...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
正常膨胀菜单...
private void actionShare(){
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "my string");
i.putExtra(Intent.EXTRA_TEXT, "another string");
startActivity(i);
//Or like above will always display the chooser
//startActivity(Intent.createChooser(i, getResources().getText(R.string.share)));
}
创建一个带有 ACTION_SEND 意图的方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_share:
actionShare();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
最后从 onOptionsItemSelected 调用这个方法
【讨论】:
ShareActionProvider更好,因为它不显示历史记录,而是所有可以共享的应用程序。
自己发起分享活动:
shareActionProvider.setShareIntent(intent);
shareActionProvider.setOnShareTargetSelectedListener(this);
@Override
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
// start activity ourself to prevent search history
context.startActivity(intent);
return true;
}
那么 ShareActionProvider 将不会将所选活动添加到共享历史记录中。
【讨论】:
java.lang.IllegalStateException: No preceding call to #readHistoricalData 而崩溃。此外,文档明确指出onShareTargetSelected:“注意:您不应在此处处理意图。此回调旨在通知客户端正在执行共享,因此客户端可以在必要时更新 UI。返回结果被忽略。始终返回 false 以保持一致性。"
我创建了自己版本的 ShareActionProvider(和支持类),您可以将它们复制到您的项目中 (https://gist.github.com/saulpower/10557956)。这不仅增加了关闭历史记录的功能,还可以过滤您想要共享的应用程序(如果您知道包名称)。
private final String[] INTENT_FILTER = new String[] {
"com.twitter.android",
"com.facebook.katana"
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.journal_entry_menu, menu);
// Set up ShareActionProvider's default share intent
MenuItem shareItem = menu.findItem(R.id.action_share);
if (shareItem instanceof SupportMenuItem) {
mShareActionProvider = new ShareActionProvider(this);
mShareActionProvider.setShareIntent(ShareUtils.share(mJournalEntry));
mShareActionProvider.setIntentFilter(Arrays.asList(INTENT_FILTER));
mShareActionProvider.setShowHistory(false);
((SupportMenuItem) shareItem).setSupportActionProvider(mShareActionProvider);
}
return super.onCreateOptionsMenu(menu);
}
【讨论】:
没有 API 可以做到这一点。但是,该类非常简单,您可以非常轻松地创建自己的不保留历史记录的ShareActionProvider 版本。您只需要使用其他排序方式(例如,按字母顺序)确定可能目标的排序顺序。
【讨论】:
澄清点:它不是“最后使用”,而是“最常使用”,跨越滑动窗口时间段。
如果您不想使用历史记录,那么在创建视图之前,请调用
yourShareActionProvider.setShareHistoryFileName(null);
此方法的描述,来自official docs(重点是我的):
设置用于保存共享历史的文件的文件名,该历史将用于排序共享目标。该文件将用于由 onCreateActionView() 创建的所有视图。默认为 DEFAULT_SHARE_HISTORY_FILE_NAME。 如果不应在会话之间保留共享历史记录,则设置为 null。
编辑:我应该澄清一下——如果没有历史记录,“最常用”的项目将不会显示,所以这是目前删除该按钮的唯一方法。
【讨论】:
java.lang.IllegalStateException: No preceding call to #readHistoricalData。
虽然已经是 2 年前的今天,但我想分享一下我的经验,因为我制作了一个自定义 ShareActionProvider 类,并在 onCreateActionView() 中添加了这一行 chooserView.getDataModel().setHistoryMaxSize(0);,它为我做了所有的魔法! .. 我在 Lollipop 设备和 API 16 模拟器设备上对其进行了测试,它运行良好。这是我的自定义类:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.internal.widget.ActivityChooserView;
import android.support.v7.widget.ShareActionProvider;
import android.view.View;
public class MyShareActionProvider extends ShareActionProvider {
/**
* Creates a new instance.
*
* @param context Context for accessing resources.
*/
public MyShareActionProvider(Context context) {
super(context);
}
@Override
public View onCreateActionView() {
ActivityChooserView chooserView = (ActivityChooserView) super.onCreateActionView();
Drawable icon;
if (Build.VERSION.SDK_INT >= 21) {
icon = getContext().getDrawable(R.drawable.share_icon);
}else{
icon = getContext().getResources().getDrawable(R.drawable.share_icon);
}
chooserView.setExpandActivityOverflowButtonDrawable(icon);
chooserView.getDataModel().setHistoryMaxSize(0);
return chooserView;
}
}
【讨论】:
androidx 中,setHistoryMaxSize() 方法无法访问... :(
像这样添加代码:
private void addShareSelectedListener() {
if (null == mShareActionProvider) return;
OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
mContex.startActivity(intent);
return true;
}
};
//Set to null if share history should not be persisted between sessions.
mShareActionProvider.setShareHistoryFileName(null);
mShareActionProvider.setOnShareTargetSelectedListener(listener);
}
【讨论】:
getSupportMenuInflater().inflate(R.menu.share_action_provider, menu);
// Set file with share history to the provider and set the share intent.
MenuItem actionItem = menu.findItem(R.id.menu_item_share_action_provider_action_bar);
ShareActionProvider actionProvider = (ShareActionProvider) actionItem.getActionProvider();
***actionProvider.setShareHistoryFileName(null);
OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
startActivity(intent);
return true;
}
};
actionProvider.setOnShareTargetSelectedListener(listener);***
【讨论】: