1. 程式人生 > >android 之Menu詳解

android 之Menu詳解

基本概念:

選單:在應用程式中有很多型別的通用應用程式元件

        A.選項選單(OptionsMenu):當用戶按手機上的選單鍵時自動彈出的選單

            onCreateOptionsMenu(Menu menu):初始化選單項時自動呼叫的方法

            onOptionsItemSelected(MenuItem item):當處理使用者點選選單項時自動呼叫的方法

        B.上下文選單(contextMenu):長按某個控制元件超過2s後彈出的選單

        C.彈出選單(PopMenu):當用戶點選某個控制元件時彈出的選單

A.選項選單

實際效果:



控制檯反饋:


 實現方式:       

<1>用java程式碼來實現

例項程式碼:

package com.hsj.example.menudemo01;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast;

/**
 *
 */
public class MainActivity extends AppCompatActivity {

    private static final int MENU_FILE = Menu.FIRST+100;
    private static final int MENU_FILE_NEW = Menu.FIRST+50;
    private static final int MENU_FILE_OPEN = Menu.FIRST+25;


    private static final int MENU_EDIT = Menu.FIRST+200;

    private static final int MENU_VIEW = Menu.FIRST+300;

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


    /**
     *
     * 建立選項選單時自動呼叫的方法
     * @param menu 選單欄物件
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        //通過java 程式碼生成一級選單項:menu.add(groupid,itemId,orderId,title)
        //menu.add(1,MENU_FILE,100,"檔案");

        //通過java 程式碼生成二級選單
        SubMenu subMenu_file=menu.addSubMenu("檔案");//指定頂級選單項的標題並返回二級選單物件
        subMenu_file.add(1,MENU_FILE_NEW,100,"新建");
        subMenu_file.add(1,MENU_FILE_OPEN,200,"開啟");

        menu.add(1,MENU_EDIT,200,"編輯");
        menu.add(1,MENU_VIEW,300,"檢視");

        System.out.println("=====onCreateOptionsMenu(Menu menu)====");
        return super.onCreateOptionsMenu(menu);
    }



    /**
     * 當用戶點選選單項時自動呼叫的方法
     * @param item 使用者點中的選單項物件
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        String title=item.getTitle().toString();
        Toast.makeText(this,"title="+title,Toast.LENGTH_LONG).show();
        System.out.println("==onOptionsItemSelected(MenuItem item="+item+")===");

        int itemId=item.getItemId();
        switch (itemId){
            case MENU_FILE:
                System.out.println("===檔案==");
                break;
            case MENU_FILE_NEW:
                System.out.println("===新建====");
                break;
            case MENU_FILE_OPEN:
                System.out.println("==開啟===");
                break;




            case MENU_EDIT:
                System.out.println("====編輯====");
                break;

            case MENU_VIEW:
                System.out.println("===檢視===");
        }

        return super.onOptionsItemSelected(item);
    }
}

<2>用佈局填充器(關聯xml)來實現

具體操作:新建一個menu檔案

例項程式碼:

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <!--
    android:id="@+id/menu_file":指定選單項的唯一標識
    android:title="File":選單項上顯示的文字,即選單標題

    android:orderInCategory="300":指定選單在類別中的排序號,數字越大越靠近手機底部
    android:enabled="false":指定選單項是否可用,true:可用,false:不可用,所謂不可用就是選單項變灰,不再響應使用者的點選操作了

    app:showAsAction="always":指定選單項的顯示方式;always:讓選單項永遠顯示在ActionBar 上
    app:showAsAction="ifRoom":如果ActionBar 上有剩餘空間則顯示在ActionBar 上,否則隱藏才選單條中
    app:showAsAction="never":當前<span class=""></span>選單項永遠不會顯示在ActionBar 上
     android:icon="@mipmap/ic_launcher":指定選單項顯示的圖示
     app:showAsAction="always|withText":當前選單項永遠顯示在ActionBar 上並且伴隨著顯示選單的標題,但是必須在橫屏上才能同時顯示,豎屏則只顯示圖示

    -->
    <item
        android:id="@+id/menu_file"
        android:orderInCategory="300"
        android:enabled="true"
        android:icon="@mipmap/ic_launcher"
        android:title="File">
        <menu>
            <item android:id="@+id/menu_new" android:title="新建">
                <menu>
                    <item android:title="新建word 檔案"></item>
                    <item android:title="新建pdf 檔案"></item>
                </menu>
            </item>
            <item android:id="@+id/menu_open" android:title="開啟"/>
            <item android:id="@+id/menu_close" android:title="關閉"/>
        </menu>
    </item>
    <item
        android:id="@+id/menu_edit"
        android:orderInCategory="200"
        app:showAsAction="ifRoom"
        android:title="Edit">

    </item>
    <item
        android:id="@+id/menu_view"
        android:orderInCategory="100"
        app:showAsAction="never"
        android:title="View">
    </item>
</menu>

後臺邏輯:

package com.hsj.example.menudemo01;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

/**
 * 選單:在應用程式中有很多型別的通用應用程式元件
 * 選單的分類:
 *      A: 選項選單(OptionsMenu):當用戶按手機上的選單鍵時彈出的選單
 *          onCreateOptionsMenu(Menu menu):初始化選單項時自動呼叫的方法
 *          onOptionsItemSelected(MenuItem item):當處理使用者點選選單項時自動呼叫的方法
 *
 *
 *      B:上下文選單(ContextMenu):長按某個控制元件超過2s 後彈出的選單
 *
 *      C:彈出選單(PopMenu):當用戶點選某個控制元件時彈出的選單
 *
 */
public class MainActivity_bak01 extends AppCompatActivity {

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


    /**
     *
     * 佈局填充器:將佈局檔案轉換成View 物件
     *
     * 建立選項選單時自動呼叫的方法
     * @param menu 選單欄物件
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        //1.得到選單填充器物件:將選單檔案轉換成選單物件並掛載到指定的選單欄上
        MenuInflater menuInflater=getMenuInflater();
        menuInflater.inflate(R.menu.menu_main,menu);


        System.out.println("=====onCreateOptionsMenu(Menu menu)====");
        return super.onCreateOptionsMenu(menu);
    }

    /**
     * 每次展開選單項時都會自動呼叫的方法,可以修改某些選單的可用性
     * @param menu
     * @return
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {

        //根據選單項的id 值查詢選單物件
        MenuItem menuItem_view=menu.findItem(R.id.menu_view);
        //設定選單項的可用性
        //menuItem_view.setEnabled(false);//禁用選單項

        //設定選單項的可見性
        menuItem_view.setVisible(false);//選單性不可見


        System.out.println("===onPrepareOptionsMenu(Menu menu)==");

        return super.onPrepareOptionsMenu(menu);//如果想顯示選單項,則當前方法必須返回true
        //return false;//不會顯示任何選單物件了
    }

    /**
     * 當用戶點選選單項時自動呼叫的方法
     * @param item 使用者點中的選單項物件
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        System.out.println("==onOptionsItemSelected(MenuItem item="+item+")===");
        //得到選單項的標題
        String title=item.getTitle().toString();
        Toast.makeText(this,"title="+title,Toast.LENGTH_LONG).show();

        int menuItemId= item.getItemId();
        switch (menuItemId){
            case R.id.menu_file:
                System.out.println("=====file====");
                break;
            case R.id.menu_edit:
                System.out.println("====edit=======");
                break;
            case R.id.menu_view:
                System.out.println("===view====");
                break;
        }

        return super.onOptionsItemSelected(item);
    }

B.上下文選單:

contextMenu:

將指定內容複製到剪下板的步驟:

1.通過系統服務得到剪下板管理器物件

this.cliphboardManager = (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);

2.得到需要剪下的內容物件

clipData = ClipData.newPlainText("text",itemContent);

3.使用剪下板管理器物件設定需要複製的剪下內容物件

clipboardManager.setPrimaryClip(clipData);

將複製的內容貼上到指定位置

1.通過剪下板管理器物件得到複製上的內容對應的物件

clipData = clipboardManager.getPrimaryClip();

2.通過剪下物件得到貼上的條目物件

item1 = clipData.getItemAt(0)

3.得到複製到剪下板上的內容

content = item1.getText().toString();

業務邏輯程式碼:

package com.hsj.example.contextmenudemo02;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 *將指定內容複製到剪下板的步驟:
 *  1.通過系統服務得到剪貼簿管理器物件
 *      this.clipboardManager= (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);
 *  2.得到需要剪貼的內容物件
 *       clipData=ClipData.newPlainText("text",itemContent);
 *  3.使用剪下板管理器物件設定需要複製的剪貼內容物件
        clipboardManager.setPrimaryClip(clipData);


  將複製的內容貼上到指定位置:
    1.通過剪貼簿管理器物件得到複製上的內容對應的物件
        clipData=clipboardManager.getPrimaryClip();
    2.通過剪下物件得到貼上的條目物件
        item1=clipData.getItemAt(0);
    3.得到複製到剪下板上的內容
        content=item1.getText().toString();

 */
public class MainActivity extends AppCompatActivity {

    private static final int MENU_FILE = Menu.FIRST + 100;
    private static final int MENU_FILE_NEW = Menu.FIRST + 50;
    private static final int MENU_FILE_OPEN = Menu.FIRST + 25;


    private static final int MENU_EDIT = Menu.FIRST + 200;
    private static final int MENU_EDIT_COPY = Menu.FIRST + 150;
    private static final int MENU_EDIT_PASTE = Menu.FIRST + 125;


    private static final int MENU_VIEW = Menu.FIRST + 300;

    private ListView listView_names;

    private List<String> data;

    private ArrayAdapter<String> adapter;


    //宣告剪貼簿管理器物件
    private ClipboardManager clipboardManager;

    //宣告剪輯物件
    private ClipData clipData;

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



        //1.通過系統服務得到剪貼簿管理器物件
         this.clipboardManager= (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);



        this.listView_names= (ListView) this.findViewById(R.id.listView_names);


        this.adapter=this.getAdapter();
        this.listView_names.setAdapter(adapter);


        //註冊上下文選單到ListView 控制元件上
        registerForContextMenu(this.listView_names);

    }

    private ArrayAdapter<String> getAdapter() {
        this.data=this.getData();
        adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data);
        return adapter;
    }

    private List<String> getData() {
        data=new ArrayList<>();
        for(int i=0;i<20;i++){
            data.add("小麗"+i);
        }
        return data;
    }


    /**
     * 初始化上下文選單物件時自動地哦啊喲的方法
     * @param menu
     * @param v
     * @param menuInfo
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        //getMenuInflater().inflate(R.menu.menu_context,menu);

        menu.add(1,MENU_VIEW,100,"檢視條目內容");
        menu.add(1,MENU_EDIT_COPY,200,"複製");
        menu.add(1,MENU_EDIT_PASTE,300,"貼上");

    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
       // String title=item.getTitle().toString();
        //Toast.makeText(this,"title="+title,Toast.LENGTH_LONG).show();


        int itemId=item.getItemId();



        //呼叫選單物件的getMenuInfo()方法得到上下文選單資訊物件ContextMenuInfo並轉換成它的子類AdapterContextMenuInfo
        AdapterView.AdapterContextMenuInfo adapterContextMenuInfo= (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

        //使用者長按的條目對應的索引值
        int position= adapterContextMenuInfo.position;
        String itemContent=data.get(position);

        ClipData.Item item1=null;
        String content=null;
        switch (itemId){
            case MENU_VIEW:
                Toast.makeText(this,"itemContent="+itemContent,Toast.LENGTH_LONG).show();
                System.out.println("===檢視===");
                break;
            case MENU_EDIT_COPY:

                //完成複製操作
                clipData=ClipData.newPlainText("text",itemContent);
                clipboardManager.setPrimaryClip(clipData);


                /*//完成貼上操作
                clipData=clipboardManager.getPrimaryClip();//通過剪貼簿管理器物件得到複製上的內容對應的物件
                item1=clipData.getItemAt(0);//通過剪下物件得到貼上的條目物件
                content=item1.getText().toString();//得到複製到剪下板上的內容

                Toast.makeText(this,"content="+content,Toast.LENGTH_LONG).show();
*/
                System.out.println("===複製===");

                break;
            case MENU_EDIT_PASTE:
                //完成貼上操作
                clipData=clipboardManager.getPrimaryClip();//通過剪貼簿管理器物件得到複製上的內容對應的物件
                item1=clipData.getItemAt(0);//通過剪下物件得到貼上的條目物件
                content=item1.getText().toString();//得到複製到剪下板上的內容

                Toast.makeText(this,"content="+content,Toast.LENGTH_LONG).show();

                System.out.println("===貼上===");
                break;
        }

        return super.onContextItemSelected(item);
    }
}

C.彈出選單

例項程式碼:

package com.hsj.example.popupmenudemo03;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.Toast;

/**
 * 彈出選單:當用戶點選某個View 時彈出的選單.
 *
 * 使用剪貼簿完成複製和貼上效果的步驟:
 *  1.通過系統服務得到剪下板管理器物件
 *  2.呼叫剪下板管理器物件的setPrimaryClip()方法設定需要複製的資料物件
 *
 */
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {


    private static final int MENU_EDIT_COPY = Menu.FIRST+100;
    private static final int MENU_EDIT_PASTE = Menu.FIRST+200;


    private ClipboardManager clipboardManager;

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

        //1.通過系統服務得到剪下板管理器物件
        this.clipboardManager= (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);
    }

    public void popup(View view){
        Button button= (Button) view;
        content=button.getText().toString();


        //1.例項化彈出選單物件,指定上下文物件和繫結的 view 物件
        PopupMenu popupMenu=new PopupMenu(this,view);
        popupMenu.setOnMenuItemClickListener(this);
        popupMenu.getMenuInflater().inflate(R.menu.menu_popup,popupMenu.getMenu());

        //2.顯示彈出選單
        popupMenu.show();

    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        String title=item.getTitle().toString();
        Toast.makeText(this, "title="+title, Toast.LENGTH_SHORT).show();



        ClipData clipData=null;
        //得到選單項的id 值
        int itemId=item.getItemId();
        switch (itemId){
            case R.id.menu_copy:

                clipData=ClipData.newPlainText("text",content);
                //2.呼叫剪下板管理器物件的setPrimaryClip()方法設定需要複製的資料物件
                clipboardManager.setPrimaryClip(clipData);

                break;

            case R.id.menu_paste:
                //3.貼上複製到剪下板管理器上的資料物件
                clipData=clipboardManager.getPrimaryClip();
                ClipData.Item itemData=clipData.getItemAt(0);
                String pasteData=itemData.getText().toString();
                Toast.makeText(this, "pasteData="+pasteData, Toast.LENGTH_SHORT).show();
                break;
        }

        return false;
    }
}