我在上下文操作栏中有一些奇怪的行为。
首先:
当我点击溢出按钮时,每隔一秒只会显示一个菜单项:
其次/第三次:
有没有办法让图标不占用太多空间?
当我将添加属性 android:showAsAction="always"
更改为所有项目时,实际上有足够的空间来显示所有图标 - 但是我的共享图标不可点击不再:
Clean Project 没有帮助。
我在我的测试设备 (Galaxy S3) 上使用 Android 4.2.2。
我什至尝试在我的 XXX 上完全刷新一个新的 ROM GS3(CyanogenMod 10.1 现在,SlimBean 之前,还删除了底部的导航栏)- 没有帮助。
我也在 Nexus 4 上试过了.有更多的空间,所以共享按钮和删除按钮是可见的。当我启动 Action 模式时,共享按钮不可点击,但当我将设备转为横向模式时它可以工作,当我将它转回纵向模式时它仍然可以工作。所以基本上在 Nexus 4 上,分享按钮在旋转之前不起作用。
list :
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
针对 minSdkVersion=17
进行编译没有任何区别。
我从这样的 fragment 开始 Action 模式:
mActionMode = activity.startActionMode(mMultipleCallback);
在 ActionMode.Callback
中,我填充了菜单:
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.management_cab, menu);
MenuItem item = menu.findItem(R.id.managementCABShare);
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
//...other stuff
return true;
}
这是 XML:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:title="@string/checkAll"
android:id="@+id/managementCABCheckAll"
android:icon="@android:drawable/checkbox_on_background">
</item>
<item
android:title="@string/enable"
android:id="@+id/managementCABEnable"
android:icon="@drawable/sphere_green">
</item>
<item
android:title="@string/disable"
android:id="@+id/managementCABDisable"
android:icon="@drawable/sphere_red">
</item>
<item
android:title="@string/delete"
android:id="@+id/managementCABDelete"
android:icon="@android:drawable/ic_menu_close_clear_cancel">
</item>
<item
android:title="@string/share"
android:id="@+id/managementCABShare"
android:actionProviderClass="android.widget.ShareActionProvider"
android:icon="@android:drawable/ic_menu_share">
</item>
<item
android:title="@string/export"
android:id="@+id/managementCABExport"
android:icon="@drawable/explorer">
</item>
</menu>
为了完整起见,整个回调
:
protected ActionMode.Callback mMultipleCallback = new ActionMode.Callback() {
private ShareActionProvider mShareActionProvider;
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.management_cab, menu);
MenuItem item = menu.findItem(R.id.managementCABShare);
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
hideUnwantedCABItems(menu);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
List<Integer> checkedPositions = getAllCheckedPositions();
switch (item.getItemId()) {
case R.id.managementCABCheckAll:
changeCheckedOfAllItems(true);
return true;
case R.id.managementCABEnable:
changeEnabled(checkedPositions, true);
return true;
case R.id.managementCABDisable:
changeEnabled(checkedPositions, false);
return true;
case R.id.managementCABDelete:
if (deleteAlert == null)
createDeleteDialog(checkedPositions);
initDeleteDialog(checkedPositions);
return true;
case R.id.managementCABShare:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportItemsAndGetUris(checkedPositions));
shareIntent.setType("application/xml");
setShareIntent(shareIntent);
return true;
case R.id.managementCABExport:
String message;
if (StorageController.copyUriListToExportFolder(exportItemsAndGetUris(checkedPositions)))
message = getActivity().getString(R.string.export_success);
else
message = getActivity().getString(R.string.export_fail);
Toast.makeText(getActivity(), message + ":\n" + StorageController.getExternalExportApplicationFolder(), Toast.LENGTH_LONG).show();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
changeCheckedOfAllItems(false);
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
private void setShareIntent(Intent shareIntent) {
if (mShareActionProvider != null) {
mShareActionProvider.setShareIntent(shareIntent);
}
}
};
最佳答案
好的,无法点击共享图标的解决方案。这是我对 API 的一种误解。
我以为你可以治疗 SharedActionProvider-Item
与菜单 XML 文件中的所有其他项目一样。但实际上你不能。 onActionItemClicked
当它显示为操作时甚至不会触发此图标(这就是为什么当您添加 showAsAction=always
时它不可点击)。有趣的是,当图标未显示但在溢出菜单中可见时会触发点击事件。 这可能是上下文操作栏中的实际错误!
现在我终于弄明白了应该如何触发 SharedActionProvider-Item
:
你必须 (!) 放一个 Intent
在onCreateActionMode
方法:
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.management_cab, menu);
MenuItem item = menu.findItem(R.id.managementCABShare);
initSharedActionProvider(item); //Check out this method in the next code fragment
return false;
}
现在你可能会说:“你这个白痴,这很明显,最好始终将 Intent 设置在那里,而不是像以前那样在 onActionItemClicked
方法中设置”。
抱歉,但我不同意:将它设置在这里并没有什么意义。原因是:对我来说, Intent 随着你检查的每一个额外项目而改变。它会为您检查的每个项目创建一个导出 XML 文件,我真的不想在每次单击图标时都创建一个 XML 文件。这是没有意义的,我希望仅当用户真正想要导出项目时才创建所有 XML 文件。
所以基本上我为此做了一个解决方法。一开始,我做了一个 Intent
并添加一个空的 List<Uri>
.这个列表在我的类中保存为一个成员变量,所以如果我向它添加项目,这些项目也会在 Intent 中。然后,当用户单击共享项目时,列表中会填充所有选定的项目。为此,我覆盖了 OnShareTargetSelectedListener
.当用户点击具体的共享目标(如电子邮件、保管箱等)时,将触发此方法。
现在这是完整的代码(该方法仅从 onCreateActionMode
调用一次):
private void initSharedActionProvider(MenuItem item) {
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
mShareActionProvider.setOnShareTargetSelectedListener(new OnShareTargetSelectedListener() {
@Override
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
//Here is the exportedFiles list populated
exportItemsAndSetList(getAllCheckedPositions());
return true;
}
});
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
//exportedFiles is a member Variable which I populate with the selected items, with the exportItemsAndSetList method
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportedFiles);
shareIntent.setType("application/xml");
mShareActionProvider.setShareIntent(shareIntent);
}
我希望你明白我在那里做了什么。如果没有,请随时询问。
有了上面的所有这些,我的一个问题就解决了(共享图标显示为图标时不可点击)- 但其他两个仍然打开(图标不应该占用太多空间和第一个问题)。
问题 2 已解决:
似乎 Android 需要更高分辨率文件夹(hdpi、xhdpi)中的图标才能真正具有更高分辨率 - 我的启用/禁用图标只有 32x32 像素的大小(我只是将它们放在所有文件夹中) 因此 Android 以某种方式弄得一团糟,所以只有三个图标适合操作栏。我刚刚删除了所有图标,但删除了 mdpi 中 32x32 像素的原始图标。现在 Android 升级了 32x32 像素的图标,可以在操作栏中显示五个项目。这有点奇怪。
问题 1 已解决:
看起来这和问题2有直接关系,我一解决问题2,删除图标就直接放在操作栏上了。
此外,通过一些测试,我发现如果我添加 showAsAction=never
,文本总是存在的到删除图标。我真的认为它与问题 2 有关(图标确实在那里做了坏事)。
我的问题差不多解决了。
我想我现在遇到了一个(新)真正的错误:最近使用的共享操作漂浮在溢出图标上。单击此处时,溢出菜单仍会打开,但看起来很糟糕:
我是如何解决这个问题的?
好吧,我受够了这个 ****,所以我刚刚添加了 showAsAction=never
到共享图标。 (是的,我看到了 this ,但如果我这样做,我会得到一个异常(exception),这也是正常生命周期的另一个变化......)
如果您知道比我使用的更好的解决方案,请随时发表评论:>
关于android - 菜单项的上下文操作栏奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16200242/