Android Contextual Menus之二:contextual action mode


 

Android Contextual Menus之二:contextual action mode

 

  接上文:Android Contextual Menus之一:floating context menu

  ContextMenu的兩種形式,上文討論了第一種形式,兼容性較好。

  本文討論第二種形式,Android 3.0,即API Level 11之后可用。

 

Contextual action mode

  Contextual action mode是 ActionMode 的系統實現,關注於執行上下文相關動作的用戶交互。

  當用戶通過選擇一個項目使能這個模式,一個contextual action bar就會出現在屏幕上方,顯示用戶對當前選中的項目可以執行的動作。

  當這個模式使能時,用戶可以:選擇多個項目(如果你允許的話)、取消項目選擇、在activity中繼續瀏覽(只要你允許)。

  當用戶取消對所有項目的選擇、按下Back鍵、或者點擊bar左邊的完成按鈕之后,action mode就被禁用,contextual action bar消失。

  注意:contextual action bar沒有必須 action bar關聯,它們是獨立的。

 

CAB的使用情形

  對於提供上下文動作的View,通常在這兩種情況下(情況之一或both)調用contextual action mode

  1.用戶在View上長按;

  2.用戶選擇了View中的CheckBox或者類似控件。

 

  你的應用如何invoke這個contextual action mode,以及如何定義每個action取決於你自己的設計。

  兩種基本的設計:

  1.對個體任意views的上下文相關操作;

  For contextual actions on individual, arbitrary views.

  2.對一組數據的批處理,比如ListView或GridView中的項目,允許用戶選擇多個項目然后對它們整體執行一個動作。

  For batch contextual actions on groups of items in a ListView or GridView (allowing the user to select multiple items and perform an action on them all).

 

  下面分別講講這兩種情景下的實現。

 

Enabling the contextual action mode for individual views

  如果你想在用戶選擇指定View的時候invoke contextual action mode(CAB),你應該:

  1.實現ActionMode.Callback接口。

  在這個接口的回調方法中,你可以指定contextual action bar的動作,響應action items的點擊事件,還有處理action mode的生命周期事件。

  2.當你想要show這個bar的時候(比如用戶長按view的時候),調用 startActionMode()方法。

  例子代碼:

package com.example.mengdd.hellocontextmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class ContextualActionModeActivity extends Activity {

    private TextView mTextView = null;
    private ActionMode mActionMode = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contextual_action_mode);

        mTextView = (TextView) findViewById(R.id.textView2);
        mTextView.setOnLongClickListener(new OnLongClickListener() {

            @Override
            public boolean onLongClick(View view) {
                if (mActionMode != null) {
                    return false;
                }

                // Start the CAB using the ActionMode.Callback defined above
                mActionMode = startActionMode(mActionModeCallback);
                view.setSelected(true);
                return true;
            }
        });
    }

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

        // Called when the action mode is created; startActionMode() was called
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate a menu resource providing context menu items
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_menu1, menu);
            return true;
        }

        // Called each time the action mode is shown. Always called after
        // onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false; // Return false if nothing is done
        }

        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
            case R.id.edit:

                showEditor();
                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
            }
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    };

    private void showEditor() {
        Toast.makeText(ContextualActionModeActivity.this, "edit",
                Toast.LENGTH_LONG).show();
    }
}
CAB Demo1

 

 

Enabling batch contextual actions in a ListView or GridView

  對於ListView和GridView這樣的集合類,想讓用戶進行批處理操作,應該如下:

  1.實現 AbsListView.MultiChoiceModeListener接口,通過setMultiChoiceModeListener()方法把它set進集合類控件。

  在這個listener的回調方法中,你可以指定contextual action bar的動作,響應action item的點擊事件,處理其他繼承自ActionMode.Callback的回調。

  2.調用 setChoiceMode()方法,使用參數 CHOICE_MODE_MULTIPLE_MODAL 。

  例子代碼:

package com.example.mengdd.hellocontextmenu;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class ListCABActivity extends ListActivity {
    private ListView mListView = null;
    private String[] mStrings = Cheeses.sCheeseStrings;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Use an existing ListAdapter that will map an array
        // of strings to TextViews
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mStrings));

        mListView = getListView();
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

        mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

            @Override
            public void onItemCheckedStateChanged(ActionMode mode,
                    int position, long id, boolean checked) {
                // Here you can do something when items are
                // selected/de-selected,
                // such as update the title in the CAB


            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                // Respond to clicks on the actions in the CAB
                switch (item.getItemId()) {
                case R.id.delete:
                    deleteSelectedItems();
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
                }
            }

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate the menu for the CAB
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.context_menu2, menu);
                return true;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                // Here you can make any necessary updates to the activity when
                // the CAB is removed. By default, selected items are
                // deselected/unchecked.
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                // Here you can perform updates to the CAB due to
                // an invalidate() request
                return false;
            }
        });

    }

    private void deleteSelectedItems() {
        Toast.makeText(ListCABActivity.this, "delete!", Toast.LENGTH_LONG)
                .show();
    }
}
CAB Demo2

 

參考資料

  API Guides: Menus->Using the contextual action mode

  http://developer.android.com/guide/topics/ui/menus.html#CAB

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM