Android之三種Menu的使用

一、OptionMenu(選項菜單)

  當用戶點擊手機menu鍵會彈出菜單,菜單在2.3系統中最多顯示6項如果超過在6項則顯示一個More。4.0以後系統中會根據屏幕的高度決定菜單的項數。

1. 創建

  爲 Activity 指定選項菜單,重寫 onCreateOptionsMenu()(Fragment 對應 onCreateOptionsMenu() 回調)。啓動 Activity 時會調用 onCreateOptionsMenu()方法,因此可以在該方法中將菜單資源(使用 XML 定義)注入到回調方法的Menu 中。 

幾個方法介紹:
public boolean onCreateOptionsMenu(Menu menu):使用此方法調用OptionsMenu。
public boolean onOptionsItemSelected(MenuItem item):選中菜單項後發生的動作。
public void onOptionsMenuClosed(Menu menu):菜單關閉後發生的動作。  
public boolean onMenuOpened(int featureId, Menu menu):單打開後發生的動作。
public boolean onPrepareOptionsMenu(Menu menu):選項菜單顯示之前onPrepareOptionsMenu方法
會被調用,你可以用此方法來根據當時的情況調整菜單。

2. 處理響應事件

  重寫 onOptionsItemSelected() 方法,方法將傳遞所選中的 MenuItem。您可以通過調用 getItemId() 方法來識別對應item,該方法將返回菜單項的唯一 ID(由菜單資源中的 android:id 屬性定義)。
  
案例演示一:

package com.vince.day10_optionsmenu;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
    }

    /**
     * 創建選項菜單
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main, menu);
        menu.add(R.id.select_color, 1, 4, "灰色");
        return super.onCreateOptionsMenu(menu);
    }

    /**
     * 處理菜單項的點擊事件
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_quit:
            finish();// 返回
            break;
        case R.id.select_color_blue:
            textView.setTextColor(Color.BLUE);
            break;
        case R.id.set_size_30:
            textView.setTextSize(20);
            break;
        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }
}

menu文件夾中的main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/action_quit"
        android:title="退出"/>
    <item android:id="@+id/select_color"
        android:title="選擇顏色">
        <menu>
            <group >
                <item android:id="@+id/select_color_blue"
                    android:title="藍色"/>
                <item android:id="@+id/select_color_red"
                    android:title="紅色"/>
                <item android:id="@+id/select_color_green"
                    android:title="綠色"/>
            </group>
        </menu>
    </item>

    <item android:id="@+id/set_size"
        android:title="設置字體大小">
        <menu >
            <group >
                <item android:id="@+id/set_size_20"
                    android:title="20"/>
                <item android:id="@+id/set_size_30"
                    android:title="30"/>
                <item android:id="@+id/set_size_40"
                    android:title="40"/>
            </group>
        </menu>
    </item>
</menu>

效果圖如下:
這裏寫圖片描述

案例演示二:

package com.vince.optiondialog2;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        /*
         * 
         * add()方法的四個參數,依次是:
         * 
         * 1、組別,如果不分組的話就寫Menu.NONE,
         * 
         * 2、Id,這個很重要,Android根據這個Id來確定不同的菜單
         * 
         * 3、順序,那個菜單現在在前面由這個參數的大小決定
         * 
         * 4、文本,菜單的顯示文本
         */

        // setIcon()方法爲菜單設置圖標,這裏使用的是系統自帶的圖標
        menu.add(menu.NONE, menu.FIRST + 1, 5, "刪除").setIcon(
                android.R.drawable.ic_menu_delete);
        menu.add(menu.NONE, menu.FIRST + 2, 2, "保存").setIcon(
                android.R.drawable.ic_menu_save);
        menu.add(menu.NONE, menu.FIRST + 3, 6, "幫助").setIcon(
                android.R.drawable.ic_menu_help);
        menu.add(menu.NONE, menu.FIRST + 4, 1, "添加").setIcon(
                android.R.drawable.ic_menu_add);
        menu.add(menu.NONE, menu.FIRST + 5, 4, "詳細").setIcon(
                android.R.drawable.ic_menu_info_details);
        menu.add(menu.NONE, menu.FIRST + 6, 3, "發送").setIcon(
                android.R.drawable.ic_menu_send);

        // 如果返回false,菜單則不會顯示
        return true;

        // return super.onCreateOptionsMenu(menu);//效果等同上面
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case Menu.FIRST + 1:
            Toast.makeText(this, "刪除菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 2:
            Toast.makeText(this, "保存菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 3:
            Toast.makeText(this, "幫助菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 4:
            Toast.makeText(this, "添加菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 5:
            Toast.makeText(this, "詳細菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 6:
            Toast.makeText(this, "發送菜單被點擊了", Toast.LENGTH_LONG).show();
            break;
        default:
            break;
        }

        return false;

        // return super.onOptionsItemSelected(item);//效果等同上面
    }

    @Override
    public void onOptionsMenuClosed(Menu menu) {
        super.onOptionsMenuClosed(menu);
        Toast.makeText(this, "選項菜單關閉了", Toast.LENGTH_LONG).show();
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        Toast.makeText(this,
                "選項菜單顯示之前onPrepareOptionsMenu方法會被調用,
                你可以用此方法來根據當時的情況調整菜
                單",Toast.LENGTH_LONG).show();

        // 如果返回false,此方法就把用戶點擊menu的動作給消費了,onCreateOptionsMenu方法將不會被調用
        return true;
    }
}

效果圖如下:
這裏寫圖片描述

二、ContexMenu(上下文菜單)

  用戶長按某一控件時出現的浮動菜單,此菜單在屏幕頂部欄顯示影響所選內容的操作項目,並允許用戶選擇多項,會直接影響對應的內容。上下文菜單是 ActionMode 的一種系統實現,它將用戶交互的重點轉到執行上下文操作上。
 
 案例演示: 

package com.danny_jiang.day10_contextmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.view.ContextMenu.ContextMenuInfo;

/**
 * 上下文菜單
 * 與選項菜單最大的不同在於:
 *      上下文菜單屬於Activity中的某一View
 *      需要長按某View之後,上下文菜單纔會顯示
 * 
 * 使用步驟:
 * 1 複寫Activity的onCreateContextMenu方法,填充上下文菜單item
 * 2 通過registerForContextMenu方法將上下文菜單註冊到某View控件上
 * 3 在onContextMenuSelected方法中攔截上下文菜單item的單擊事件
 *
 */
public class MainActivity extends Activity {

    private TextView text;
    private ListView listView;

    private String[] data = new String[]{"卡卡西", "路飛", "柯南"};

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

        text = (TextView) findViewById(R.id.text);
        listView = (ListView) findViewById(R.id.list_Main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);

        // 註冊上下文菜單到View控件
        registerForContextMenu(text);
        registerForContextMenu(listView);
    }

    /**
     * 創建上下文菜單內容
     * @param menu  所創建的菜單對象,需要將菜單item填充到此menu對象
     * @param menuInfo  
     *      是對上下文菜單的信息描述對象
     *      當攔截到上下文的單擊事件時,可以通過此對象獲取所點擊item的信息
     *      如果此對象是AdapterContextMenuInfo,說明registerForContextMenu傳入的參數是AdapterView
     *      
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        String title = null;
        /**
         * 如果註冊的是AdapterView,需要將ContextMenuInfo強轉成AdapterContextMenuInfo
         * 然後獲取所長按的item位置position
         */
        if(menuInfo instanceof AdapterContextMenuInfo) {
            AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
            int position = adapterMenuInfo.position;
            title = data[position];
        }else {
            title = "非AdapterView控件";
        }

        // 設置上下文菜單的圖標
        menu.setHeaderIcon(R.drawable.ic_launcher);
        // 設置上下文菜單的標題
        menu.setHeaderTitle("人物特徵: " + title);
        getMenuInflater().inflate(R.menu.context_menu, menu);
    }

    /**
     * 攔截上下文菜單item的單擊事件
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        String title = item.getTitle().toString();
        switch (item.getItemId()) {
        case R.id.action_a:
            Toast.makeText(this, "點擊了 " + title, Toast.LENGTH_SHORT).show();
            break;

        default:
            break;
        }

        return super.onContextItemSelected(item);
    }
}

activity_main.xml佈局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ListView
        android:id="@+id/list_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

context_menu.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_a"
        android:title="時間過得很快">
    </item>
    <item
        android:id="@+id/action_b"
        android:title="夜幕即將降臨">
    </item>
    <item
        android:id="@+id/action_c"
        android:title="我覺得我必須要離開">
    </item>

</menu>

效果圖如下:
這裏寫圖片描述
  
這裏寫圖片描述

考慮到篇幅原因,關於ActionMode的系統實現原理,不在此贅述,感興趣可參考博客http://blog.csdn.net/evan_man/article/details/51685022

三、PopupMenu

  PopupMenu 是錨定到 View 的動態菜單。如果空間足夠,它將顯示在定位視圖左下方,否則顯示在其左上方。適用於提供與特定內容相關的大量操作,或者爲命令的另一部分提供選項,不會直接影響對應的內容。
  
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

案例演示:

package com.danny_jiang.day10_popmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.TextView;

/**
 * PopMenu的使用步驟
 * 1 初始化PopMenu對象
 *      需要傳入一個所依賴的View對象,當彈出菜單時,所依賴的位置對象
 * 2 PopMenu設置item單擊事件
 * 3 調用PopMenu.show方法將其顯示
 *
 */
public class MainActivity extends Activity implements OnClickListener {

    private TextView text;
    private Button btn;

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

        text = (TextView) findViewById(R.id.text);
        btn = (Button) findViewById(R.id.button);

        text.setOnClickListener(this);
        btn.setOnClickListener(this);
    }

    /**
     * @param v 就是所點擊的View控件
     */
    @Override
    public void onClick(View v) {
        showPopMenu(v);
    }

    /**
     * 顯示彈出式菜單:寬度、高度
     * 當點擊寬度或者高度時,將所點擊的View屬性設置到Activity的Title中
     */
    private void showPopMenu(final View v) {
        // 創建PopMenu,並設置彈出菜單的item
        PopupMenu popMenu = new PopupMenu(this, v);
        popMenu.getMenuInflater().inflate(R.menu.pop_menu, popMenu.getMenu());
        // 設置點擊事件
        popMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                case R.id.width:
                    // 通過View.getWidth方法獲取View控件的寬度
                    int width = v.getWidth();
                    // 通過Activity.setTitle方法,可以直接設置Activity的標題欄
                    setTitle(width + "");
                    break;
                case R.id.height:
                    int height = v.getHeight();
                    setTitle(height + "");
                    break;

                default:
                    break;
                }
                return false;
            }
        });

        // 顯示彈出式菜單
        popMenu.show();

    }
}

pop_menu.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/width"
        android:title="寬度"/>
    <item
        android:id="@+id/height"
        android:title="高度"/>

</menu>

效果圖如下:
這裏寫圖片描述

參考博客:http://www.cnblogs.com/xiajf/p/4560831.html
http://blog.csdn.net/evan_man/article/details/51685022
轉載請註明出處,謝謝!http://blog.csdn.net/sq19920518/article/details/52644310

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章