2013-04-24 93 views
10

我在上下文操作欄中有一些奇怪的行爲。上下文操作欄菜單項的怪異行爲

首先:

一個菜單項時,纔會顯示每次我第二次單擊溢出按鈕:

Clicking behavior overflow button of CAB

二/三:

有沒有一種方式,圖標不要使用太多的空間?

當我改變添加屬性android:showAsAction="always"所有項目,有實際足夠的空間來顯示所有的圖標 - 我的共享圖標是不可點擊了:

All Items with showAsAction always

清理項目不幫幫我。

我在我的測試設備(Galaxy S3)上使用Android 4.2.2。

我甚至試圖完全刷新我的XXX GS3(CyanogenMod 10.1現在,在SlimBean之前,也刪除底部的導航欄)的新ROM - 沒有幫助。我也嘗試過Nexus 4。有更多的空間,所以共享按鈕和刪除按鈕是可見的。分享按鈕不是當我啓動操作模式時可點擊,但是當我將設備設置爲橫向模式時,它可以正常工作,並且當我將其恢復爲縱向時,它仍然有效。因此,基本上在Nexus 4上,分享按鈕在旋轉之前不起作用。


清單:

<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進行編譯? – 2013-04-24 19:20:07

+0

wtf爲什麼倒票?反正我的設備上使用4.2.2 - 檢查編輯澄清 – 2013-04-24 19:25:35

+0

那不是我,如果你對編譯V14我會嘗試先對編譯最新的SDK。 – 2013-04-24 19:29:01

回答

9

好的,解決方案的不可點擊的共享圖標。這是我對API的一種誤解。

我以爲你可以像你的菜單XML文件中的其他項一樣處理SharedActionProvider-Item。但實際上你不能。當它顯示爲一個動作時,這個圖標甚至不會觸發onActionItemClicked(這就是爲什麼當您添加showAsAction=always時它不可點擊)。有趣的是,當圖標沒有顯示時,點擊事件被觸發,但它在溢出菜單中可見。 這可能是上下文操作欄中的實際錯誤!

現在我終於想通了,你應該如何觸發SharedActionProvider-Item

你必須把一個IntentonCreateActionMode方法(!):

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的需要這是在更高分辨率的文件夾(華電國際,xhdpi)真的是在一個更高的分辨率的圖標 - 我的啓用/禁用圖標只有大小爲32x32像素(我只是將它們放在所有文件夾中),因此Android在某種程度上造成了很大的混亂,因此只有三個圖標適合操作欄。我只是刪除所有圖標,但在mdpi中的原始的32x32像素。現在,Android可以放大32x32像素圖標,並可以在操作欄中顯示五項。這有點奇怪。


問題1種解決:

看起來這直接關係到問題2,只要我解決問題2,刪除圖標直接放在動作條上。

還有一些測試,我看到如果我將showAsAction=never添加到刪除圖標,文本總是在那裏。我真的認爲它與問題2有關(圖標真的在那裏做壞事)。


我的問題幾乎解決了。

我想我現在得到了一個(新)實際錯誤:最近使用的共享操作浮動在溢出圖標上。當點擊那裏,溢出菜單仍然打開,但它看起來非常低劣:

Most recent share icon above overflow icon

我怎麼解決這個問題?

嗯,我用這個****亂搞做,所以我剛纔添加的showAsAction=never到共享圖標。 (是的,我看到this,但我得到一個異常,如果我這樣做,也是它的正常生命週期的另一個變化......)

隨意評論,如果你知道更好的解決方案比我用:>