菜单项的上下文动作栏怪异行为

我在上下文操作栏中有一些奇怪的行为。

首先:

一个菜单项只显示每隔一次我点击溢出button:

点击CAB的行为溢出按钮

其次/第三:

有没有一种方法,图标不占用太多的空间?

当我更改所有项目添加属性android:showAsAction="always" ,实际上有足够的空间来显示所有图标 – 我的共享图标不再可点击:

所有带showAsAction的项目总是

清洁项目没有帮助。

我在我的testing设备(Galaxy S3)上使用Android 4.2.2。

我甚至试图完全刷新我的XXX GS3( CyanogenMod 10.1现在, SlimBean之前,也删除了底部的导航栏)的新ROM – 没有帮助。

我也试过Nexus 4 。 有更多的空间,所以共享button和删除button是可见的。 当我开始操作模式时,分享button不可点击,但是当我将设备转换为横向模式时,它可以正常工作,当我将其恢复为纵向时,它仍然可以正常工作。 因此,基本上在Nexus 4上,分享button在旋转之前不起作用。


performance:

 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> 

minSdkVersion=17编译没有区别。

我从这样一个片段开始动作模式:

 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> 

为了完整起见,整个callback

 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); } } }; 

Solutions Collecting From Web of "菜单项的上下文动作栏怪异行为"

好的,解决scheme的不可点击的共享图标。 这是我对API的误解。

我以为你可以像你的菜单XML文件中的其他SharedActionProvider-Item一样对待SharedActionProvider-Item 。 但实际上你不能。 当它作为一个动作显示时, onActionItemClicked甚至不会触发这个图标(这就是为什么当你添加showAsAction=always时它不可点击)。 有趣的是,当没有显示图标时触发点击事件,但在溢出菜单中可见。 这可能是上下文操作栏中的实际错误!

现在我终于想出了如何触发SharedActionProvider-Item

您必须(!)在onCreateActionMode方法中放置一个Intent

 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; } 

现在你可能会说:“你这个笨蛋,这是显而易见的,而且最好总是将意图设置在那里,而不是像以前那样在onActionItemClicked方法中。

对不起,我不同意:在这里设置它没有意义。 原因是:对我来说,意图随着你检查的每一个额外的项目而改变。 它会为您检查的每个项目创build一个导出XML文件,而且我实在不希望每次单击图标时都创build一个XML文件。 这是没有道理的,我希望所有的XML文件只有在用户真的想要导出项目时才能创build。

所以基本上我为此做了一个解决方法。 一开始,我制作一个Intent并添加一个空的List<Uri> 。 这个列表保存为我的类中的成员variables,所以如果我添加项目,项目也将在意图。 然后,当用户单击共享项目时,列表将填充所有选定的项目。 为了完成这个我覆盖了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)中的图标真的是更高的分辨率 – 我的启用/禁用图标只有32×32像素(我只是把它们放在所有文件夹中),因此Android做了一个大混乱,所以只有三个图标适合在操作栏上。 我只是删除所有的图标,但在mdpi 32×32像素的原始的。 现在,Android可以升级32×32像素图标,并可以在操作栏中显示五个项目。 这有点奇怪。


问题1解决了:

看起来这是直接关系到问题2,只要我解决了问题2,删除图标被直接放置在操作栏上。

也有一些testing,我看到,如果我添加showAsAction=never删除图标文本总是在那里。 我真的认为这与问题2有关(图标真的在那里做坏事)。


我的问题几乎解决了。

我想我现在得到了一个(新)真正的bug :最近使用的共享操作浮在溢出图标上。 点击那里,溢出菜单仍然打开,但它看起来很低劣:

溢出图标上方最近的共享图标

我是如何解决这个问题的?

那么我已经完成了与这个****搞乱,所以我只是将showAsAction=never添加到共享图标。 (是的,我看到了这一点 ,但如果我这样做,我会得到一个例外,也是正常生命周期的另一个变化…)

随意评论,如果你知道比我更好的解决scheme:>