簡體   English   中英

上下文操作欄菜單項的奇怪行為

[英]Contextual action bar weird behavior for menu item

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

首先:

只有每次我點擊溢出按鈕時,才會顯示一個菜單項:

單擊CAB的行為溢出按鈕

第二/第三:

有沒有辦法讓圖標不占用太多空間?

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

所有帶showAsAction的項目總是如此

清潔項目沒有幫助。

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

我甚至試圖在我的XXX GS3上完全刷新一個新的ROM( CyanogenMod 10.1現在,在SlimBean之前,也刪除了底部的導航 ) - 沒有幫助。

我也在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);
        }
    }
};

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

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

現在我終於弄明白你應該如何觸發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方法中一樣,就像你之前做的那樣”。

對不起,但我不同意:在這里設置它沒有多大意義。 原因是:對我來說,意圖會隨着您檢查的每個附加項目而改變。 它為您檢查的每個項創建一個export-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添加到共享圖標。 (是的,我看到了這個 ,但如果我這樣做,我會得到一個例外,這也是正常生命周期的另一個變化......)

如果您知道比我使用的更好的解決方案,請隨意發表評論:>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM