2013-04-24 3 views
10

У меня есть странное поведение в контекстной панели действий.Странное поведение в контекстном режиме для пункта меню

Во-первых:

Один пункт меню отображается только каждый второй раз, когда я нажимаю на кнопку перелива:

Clicking behavior overflow button of CAB

Во-вторых/третьих:

Есть ли способ, что иконки не используйте столько места?

Когда я изменяю добавить свойство android:showAsAction="always" ко всем элементам, есть на самом деле достаточно места, чтобы показать все иконки - но мой значок доля не кликабельны больше:

All Items with showAsAction always

Clean Project не Помогите.

Я использую Android 4.2.2 на своем тестовом устройстве (Galaxy S3).

Я даже пытался полностью прошить новую ROM на моем XXX GS3 (CyanogenMod 10.1 теперь перед SlimBean, также удалены Панель навигации на внизу) - не помогло.

Я также пробовал это на Nexus 4. Больше места, поэтому кнопка совместного доступа и кнопка удаления видны. Кнопка share не является кликабельным при запуске режима действия, но когда я включаю устройство в альбомный режим, он работает, и когда я верну его обратно к портрету, он все еще работает. Таким образом, в основном на Nexus 4 кнопка совместного доступа не работает до поворота.


Manifest:

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

Вы используете v14 на своем устройстве или работаете с v14 SDK? –

+0

wtf почему голос? в любом случае я использую 4.2.2 на своем устройстве - проверьте изменения для уточнения –

+0

Это не я, если вы скомпилируете против v14, я сначала попытаюсь скомпилировать с последним SDK. –

ответ

9

Хорошо, решение для незакрепленной значки общего доступа. Это было неправильное понимание от меня к 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; 
} 

Теперь вы можете сказать: «Вы идиот , это было очевидно, и даже лучше установить намерение всегда там, а не в методе onActionItemClicked, как вы это делали раньше ».

Извините, но я не согласен: на самом деле нет смысла устанавливать его здесь. Причина: для меня намерение меняется с каждым дополнительным элементом, который вы проверяете. Он создает файл export-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 нужны иконки, которые находятся в более высоких папках разрешения (ИПЧР, xhdpi) на самом деле, чтобы быть в более высоком разрешении - мои включить/отключить значок был только размером 32x32 пикселя (и я просто помещал их во все папки), и поэтому Android сделал какой-то большой беспорядок, поэтому только три значка действительно вписывались в панель действий. Я просто удалил все значки, но оригинальные из 32x32 пикселей в mdpi. Теперь Android расширяет иконки 32x32 пикселей и может отображать пять элементов в панели действий. Это странно.


Проблема 1 вид решена:

Похоже, это было непосредственно связано с проблемой 2, как только я решил проблему 2, удаления значок был помещен непосредственно на панели действий.

Также с некоторыми испытаниями я видел, что текст всегда был там, если я добавил showAsAction=never на значок удаления. Я действительно думаю, что это как-то связано с проблемой 2 (значки действительно делали плохие вещи там).


Мои проблемы почти решены.

Я думаю, что у меня есть (новая) настоящая ошибка сейчас: последнее действие, используемое share, плавает над значком переполнения. При нажатии там, меню переполнения все еще открывается, но это выглядит довольно хреново:

Most recent share icon above overflow icon

Как мне это исправить?

Ну, я покончил с этим ****, поэтому я просто добавил showAsAction=never к значку общего доступа. (И да, я видел this, но я получаю исключение, если я делаю это, и это еще одно изменение нормального жизненного цикла ...)

Не стесняйтесь комментировать, если Вы знаете, лучшее решение, чем я использовал:>