代码改变世界

onCreateOptionsMenu与onCreateContextMenu差别

2013-11-21 08:26  Andy Ge  阅读(1518)  评论(0编辑  收藏  举报

onCreateOptionsMenu只会在启动时调用一次,而onCreateContextMenu则每次都会调用,这是因为onCreateContextMenu需要为所有的View控件的上下文菜单服务,可能会在存在多个控件都绑定了上下文的情况,针对每个控件的上下文菜单事件都需要即时处理,但Android设计应该有个可以持久化的方案,从而避免每次都需要重新加载菜单项。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="可通过上下文菜单修改背景色"
        android:textSize="15pt" />

    <TextView
        android:id="@+id/txt2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="可通过上下文菜单修改前景色"
        android:textSize="15pt" />

</LinearLayout>

my_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="@string/font_size"
        android:icon="@drawable/font">
        <menu>
            <!-- 定义一组单选菜单项 -->
            <group android:checkableBehavior="single">
                <!-- 定义多个菜单项 -->
                <item
                    android:id="@+id/font_10"
                    android:title="@string/font_10"/>
                <item
                    android:id="@+id/font_12"
                    android:title="@string/font_12"/>
                <item
                    android:id="@+id/font_14"
                    android:title="@string/font_14"/>
                <item
                    android:id="@+id/font_16"
                    android:title="@string/font_16"/>
                <item
                    android:id="@+id/font_18"
                    android:title="@string/font_18"/>                                                                
            </group>
        </menu>
    </item>
    <!-- 定义一个普通菜单项 -->
    <item android:id="@+id/plain_item"
        android:title="@string/plain_item">
    </item>
    <item android:title="@string/font_color"
        android:icon="@drawable/color">
        <menu>
            <!-- 定义一组允许复选的菜单项 -->
            <group>
                <!-- 定义3个菜单项 -->
                <item
                    android:id="@+id/red_font"
                    android:title="@string/red_title"/>
                <item
                    android:id="@+id/green_font"
                    android:title="@string/green_title"/>
                <item
                    android:id="@+id/blue_font"
                    android:title="@string/blue_title"/>                        
            </group>
        </menu>
    </item>
</menu>

context.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 定义一组单选菜单项目 -->
    <group android:checkableBehavior="single">
        <!-- 定义3个菜单项 -->
        <item
            android:id="@+id/red"
            android:title="@string/red_title"
            android:alphabeticShortcut="r"/>
        <item
            android:id="@+id/green"
            android:title="@string/green_title"
            android:alphabeticShortcut="g"/>
        <item
            android:id="@+id/blue"
            android:title="@string/blue_title"
            android:alphabeticShortcut="b"/>                        
    </group>  
</menu>

context2.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 定义一组单选菜单项目 -->
    <group android:checkableBehavior="single">
        <!-- 定义3个菜单项 -->
        <item
            android:id="@+id/white"
            android:title="@string/white_title"
            android:alphabeticShortcut="r"/>
        <item
            android:id="@+id/black"
            android:title="@string/black_title"
            android:alphabeticShortcut="g"/>
        <item
            android:id="@+id/gray"
            android:title="@string/gray_title"
            android:alphabeticShortcut="b"/>                        
    </group>  
</menu>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MenuResTest!</string>
    <string name="app_name">使用XML资源文件定义菜单</string>
    <string name="red_title">红色</string>
    <string name="blue_title">蓝色</string>
    <string name="green_title">绿色</string>
    <string name="white_title">白色</string>
    <string name="black_title">黑色</string>
    <string name="gray_title">灰色</string>
    <string name="font_size">字体大小</string>
    <string name="font_color">字体颜色</string>        
    <string name="plain_item">普通菜单项</string>
    <string name="font_10">10号字体</string>    
    <string name="font_12">12号字体</string>    
    <string name="font_14">14号字体</string>    
    <string name="font_16">16号字体</string>    
    <string name="font_18">18号字体</string>    
</resources>

MenuResText.java

package org.crazyit.ui;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Description: <br/>
 * site: <a href="http://www.crazyit.org">crazyit.org</a> <br/>
 * Copyright (C), 2001-2014, Yeeku.H.Lee <br/>
 * This program is protected by copyright laws. <br/>
 * Program Name: <br/>
 * Date:
 * 
 * @author Yeeku.H.Lee kongyeeku@163.com
 * @version 1.0
 */
public class MenuResTest extends Activity {
    private TextView txt,txt2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txt = (TextView) findViewById(R.id.txt);
        txt2 = (TextView) findViewById(R.id.txt2);
        // 为文本框注册上下文菜单
        registerForContextMenu(txt);
        registerForContextMenu(txt2);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflator = new MenuInflater(this);
        // 状态R.menu.context对应的菜单,并添加到menu中
        inflator.inflate(R.menu.my_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    int selectedIndex1 = -1;
    int selectedIndex2 = -1;

    // 创建上下文菜单时触发该方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View source,
            ContextMenu.ContextMenuInfo menuInfo) {
        int vId = source.getId();
        MenuInflater inflator = new MenuInflater(this);
        if (vId == R.id.txt) {
            // 状态R.menu.context对应的菜单,并添加到menu中
            inflator.inflate(R.menu.context, menu);
            menu.setHeaderIcon(R.drawable.tools);
            menu.setHeaderTitle("请选择背景色");
            if (selectedIndex1 >= 0) {
                menu.getItem(selectedIndex1).setChecked(true);
            }
        }
        else if(vId == R.id.txt2)
        {
            // 状态R.menu.context对应的菜单,并添加到menu中
            inflator.inflate(R.menu.context2, menu);
            menu.setHeaderTitle("请选择前景色");
            if (selectedIndex2 >= 0) {
                menu.getItem(selectedIndex2).setChecked(true);
            }
        }
    }

    // 上下文菜单中菜单项被单击时触发该方法。
    @Override
    public boolean onContextItemSelected(MenuItem mi) {
        switch (mi.getItemId()) {
        case R.id.red:
            selectedIndex1 = 0;
            txt.setBackgroundColor(Color.RED);
            break;
        case R.id.green:
            selectedIndex1 = 1;
            txt.setBackgroundColor(Color.GREEN);
            break;
        case R.id.blue:
            selectedIndex1 = 2;
            txt.setBackgroundColor(Color.BLUE);
            break;
        case R.id.white:
            selectedIndex2 = 0;
            txt2.setTextColor(Color.WHITE);
            break;
        case R.id.black:
            selectedIndex2 = 1;
            txt2.setTextColor(Color.BLACK);
            break;
        case R.id.gray:
            selectedIndex2 = 2;
            txt2.setTextColor(Color.GRAY);
            break;
        }
        return true;
    }

    @Override
    // 选项菜单的菜单项被单击后的回调方法
    public boolean onOptionsItemSelected(MenuItem mi) {
        if (mi.isCheckable()) {
            mi.setChecked(true); //
        }
        // 判断单击的是哪个菜单项,并针对性的作出响应。
        switch (mi.getItemId()) {
        case R.id.font_10:
            txt.setTextSize(10 * 2);
            break;
        case R.id.font_12:
            txt.setTextSize(12 * 2);
            break;
        case R.id.font_14:
            txt.setTextSize(14 * 2);
            break;
        case R.id.font_16:
            txt.setTextSize(16 * 2);
            break;
        case R.id.font_18:
            txt.setTextSize(18 * 2);
            break;
        case R.id.red_font:
            txt.setTextColor(Color.RED);
            mi.setChecked(true);
            break;
        case R.id.green_font:
            txt.setTextColor(Color.GREEN);
            mi.setChecked(true);
            break;
        case R.id.blue_font:
            txt.setTextColor(Color.BLUE);
            mi.setChecked(true);
            break;
        case R.id.plain_item:
            Toast toast = Toast.makeText(MenuResTest.this, "您单击了普通菜单项",
                    Toast.LENGTH_SHORT);
            toast.show();
            break;
        }
        return true;
    }
}

截图:

image

image

image

image