Странное поведение контекстной панели действий для пункта меню
У меня странное поведение в контекстной панели действий.
Во-первых:
Один пункт меню отображается только каждый раз, когда я нажимаю кнопку переполнения:
Во-вторых / в-третьих:
Есть ли способ, чтобы значки не занимали так много места?
Когда я изменяю добавить свойство android:showAsAction="always"
для всех элементов на самом деле достаточно места для отображения всех значков, но на моем значке общего доступа больше нельзя нажимать:
Чистый проект не помогает.
Я использую Android 4.2.2 на своем тестовом устройстве (Galaxy S3).
Я даже пытался полностью прошить новое ПЗУ на своем XXX GS3 ( CyanogenMod 10.1 сейчас, до SlimBean, тоже убрал панель навигации внизу) - не помогло.
Я также попробовал это на Nexus 4. Здесь больше места, поэтому видны кнопка "Поделиться" и кнопка "Удалить". Кнопка "Поделиться" недоступна, когда я запускаю режим действия, но когда я переключаю устройство в альбомный режим, оно работает, а когда я возвращаю его в портретное положение, оно все еще работает. Так что в основном на Nexus 4 кнопка "Поделиться" не работает до вращения.
Manifest:
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
Компиляция против minSdkVersion=17
не имеет значения.
Я запускаю Action Mode из фрагмента, подобного этому:
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);
}
}
};
1 ответ
Ладно, решение для значка unclickable. Это было своего рода недоразумение от меня к API.
Я думал, что вы могли бы лечить SharedActionProvider-Item
как и любой другой элемент в вашем XML-файле меню. Но на самом деле вы не можете. onActionItemClicked
даже не запускается для этого значка, когда он отображается как действие (вот почему он не активируется при добавлении showAsAction=always
). Забавно, но событие click срабатывает, когда значок не отображается, но отображается в меню переполнения. Это может быть реальной ошибкой в контекстной панели действий!
Теперь я наконец выяснил, как вы должны вызвать 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;
}
Теперь вы можете сказать: "Вы идиот, это было очевидно, и даже лучше всегда ставить цель вместо этого, как в onActionItemClicked
Метод, как вы делали раньше ".
Извините, но я не согласен: не имеет смысла устанавливать его здесь. Причина в том, что для меня намерение меняется с каждым дополнительным предметом, который вы проверяете. Он создает файл экспорта-XML для каждого элемента, который вы проверяете, и я действительно не хочу создавать файл XML при каждом нажатии на значок. Это не имеет смысла, и я хочу, чтобы все файлы XML создавались только тогда, когда пользователь действительно хочет экспортировать элементы.
В общем, я сделал обходной путь для этого. В начале я делаю Intent
и добавить пустое List<Uri>
, Этот список сохраняется как переменная-член в моем классе, поэтому, если я добавлю в него элементы, они также будут в намерении. Затем, когда пользователь щелкает элемент общего доступа, список заполняется всеми выбранными элементами. Для достижения этой цели я преодолел OnShareTargetSelectedListener
, Этот метод запускается, когда пользователь нажимает на конкретную цель общего ресурса (например, электронная почта, Dropbox и т. Д.).
Теперь вот весь код для этого (метод вызывается только один раз из 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 как-то сильно запутался, поэтому на панели действий поместились только три иконки. Я просто удалил все иконки, кроме оригинальных 32x32 пикселей в формате MDI. Теперь Android масштабирует иконки размером 32x32 пикселей и может отображать пять элементов на панели действий. Это немного странно.
Проблема 1 вида решена:
Похоже, это было напрямую связано с проблемой 2, как только я решил проблему 2, значок удаления был помещен прямо на панель действий.
Также с некоторым тестированием я увидел, что текст всегда был там, если я добавил showAsAction=never
на значок удаления. Я действительно думаю, что это как-то связано с проблемой 2 (значки там действительно плохо работали).
Мои проблемы почти решены.
Я думаю, что теперь у меня есть (новая) реальная ошибка: последнее использовавшееся действие общего доступа находится над значком переполнения. При щелчке там открывается меню переполнения, но оно выглядит довольно дерьмово:
Как я это исправил?
Ну, я закончил возиться с этим ****, так что я просто добавил showAsAction=never
на значок общего доступа. (И да, я видел это, но я получаю исключение, если я сделаю это, также это еще одно изменение нормального жизненного цикла...)
Не стесняйтесь комментировать, если вы знаете лучшее решение, чем я использовал:>