• 使用XML文件定义菜单


    •       Android提供了两种创建菜单的方式,一种是在Java代码中创建,一种使用XML资源文件定义。上面的实例都是在Java代码中创建菜单,在Java代码中创建菜单存在如下不足。
    • 在Java代码中定义菜单、菜单项,必然导致代码臃肿。
    • 需要程序员采用硬编码的方式为每个菜单项分配ID、为每个菜单组分配ID,这种方式导致应用可扩展性、可维护性降低。

          一般推荐使用XML资源文件来定义菜单,这种方式可以提高更好的解耦。

          菜单资源文件通常应该放在/res/menu目录下,菜单资源的根元素通常是<menu.../>元素,<menu.../>元素无须指定任何属性。<menu.../>元素内可包含如下子元素。

    •  <item.../>元素:定义菜单项。
    • <group.../>子元素:将多个<item.../>定义的菜单包装成一个菜单组。<group.../>子元素用于控制整组菜单的行为,该元素可以指定如下常用属性。
    • checkableBehavior:指定该组菜单的选择行为。可指定为none(不可选)、all(多选)和single(单选)三个值。
    • menuCategory:对菜单进行分类,指定菜单的优先级。有效值为container、system、secondary和alternative。
    • visible:指定改组菜单是否可见。
    • enable:指定该组菜单是否可用。

        <item.../>元素用于指定一份菜单项,<item.../>元素又可包含<menu.../>元素,位于<item.../>元素内部的<menu.../>就代表子菜单。

          <item.../>元素可以指定如下常用属性。

    • android:id:为菜单项指定一个唯一标识。
    • android:title:指定菜单项的标题。
    • android:icon:指定菜单项的图标。
    • android:alphabeticShortcut:为菜单项指定字符快捷键。
    • android:numericShortcut:为菜单项指定数字快捷键。
    • android:checkable:设置该菜单项是否可选。
    • android:checked:设置该菜单项是否已选中。
    • android:visible:设置该菜单项是否可见。
    • android:enable:设置该菜单项是否可用。

         一旦在程序中定义了菜单资源后,接下来还是重写onCreateOptionsMenu(用于创建选项菜单)、onCreateContextMenu(用于创建上下文菜单)方法,在这些方法中调用MenuInflater对象的inflate方法装载指定资源对应的菜单即可。

         接下来将会开发一个使用XML资源定义菜单的实例,本实例将会把前面开发的菜单示例程序改为使用XML资源定义菜单。

        实例:使用XML资源定义菜单

        本实例包含两种菜单:选项菜单和上下文菜单,其中国选项菜单对应的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:showAsAction="always|withText"
            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:showAsAction="always|withText"
             android:title="@string/plain_item"></item>
         <item android:title="@string/font_color"
               android:showAsAction="always"
             android:icon="@drawable/color">
             <menu>
                 <!-- 定义一组普通菜单项 -->
                <group>
                    <!-- 定义三个菜单项 -->
                    <item android:id="@+id/red_font"
                        android:title="@string/red_title"/>
                    <item android:id="@+id/green_font"
                        android:title="@string/green_title">
                    </item>
                     <item android:id="@+id/blue_font"
                        android:title="@string/blue_title"></item>
                </group>
             </menu>
         </item>
    </menu>

    上面的菜单资源文件的<menu.../>元素里包含三个<item.../>子元素,这表明该菜单里包含三个菜单项。其中第一个、第三个都包含子菜单。

      接下来再为该应用定义上下文菜单的资源文件,代码如下。

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <!-- 定义一组单选菜单项目 -->
        <group android:checkableBehavior="single">
            <!-- 定义三个菜单项 -->
            <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>

    定义了上面两份菜单资源之后,接下来即可在Activity的onCreateOptionsMenu、onCreateContextMenu方法中加载这两份菜单资源。下面是该程序中加载并显示两份菜单的Java代码。

    package org.crazyit.helloworld;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.graphics.Color;
    import android.view.ContextMenu;
    import android.view.ContextMenu.ContextMenuInfo;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.TextView;
    
    import android.widget.Toast;
    
    public class MenuResTest extends Activity {
    
        private TextView txt;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.menu_res_test);
            txt=(TextView)findViewById(R.id.txt);
            //为文本框注册上下文菜单
            registerForContextMenu(txt);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflator=new MenuInflater(this);
            //装填R.menu.my_menu对应的菜单,并添加到menu中
            inflator.inflate(R.menu.my_menu, menu);
            // Inflate the menu; this adds items to the action bar if it is present.
            //getMenuInflater().inflate(R.menu.menu_res_test, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo menuInfo) {
            MenuInflater inflator=new MenuInflater(this);
            //装填R.menu.context对应的菜单,并添加到menu中
            inflator.inflate(R.menu.context, menu);
            menu.setHeaderIcon(R.drawable.tools);
            menu.setHeaderTitle("选择背景色");
            // TODO Auto-generated method stub
            //super.onCreateContextMenu(menu, v, menuInfo);
        }
       //上下文菜单中,菜单项被单击时触发该方法
        @Override
        public boolean onContextItemSelected(MenuItem mi) {
            //勾选菜单项
            mi.setCheckable(true);  //①
            switch(mi.getItemId())
            {
            case R.id.red:
                mi.setCheckable(true);
                txt.setBackgroundColor(Color.RED);
                break;
            case R.id.green:
                mi.setCheckable(true);
                txt.setBackgroundColor(Color.GREEN);
                break;
            case R.id.blue:
                mi.setCheckable(true);
                txt.setBackgroundColor(Color.BLUE);
                break;
            }
            return true;
            // TODO Auto-generated method stub
            //return super.onContextItemSelected(item);
        }
        //菜单项被单击后的回调方法
        @Override
        public boolean onOptionsItemSelected(MenuItem mi) {
            if(mi.isCheckable())
            {
                //勾选该菜单项
                mi.setCheckable(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.setCheckable(true);
                break;
            case R.id.green_font:
                txt.setTextColor(Color.GREEN);
                mi.setCheckable(true);
                break;
            case R.id.blue_font:
                txt.setTextColor(Color.BLUE);
                mi.setCheckable(true);
                break;
            case R.id.plain_item:
            Toast toast=Toast.makeText(MenuResTest.this, "您单击了普通菜单项",Toast.LENGTH_SHORT);
            toast.show();
                break;
            
            }
            // TODO Auto-generated method stub
            //return super.onOptionsItemSelected(mi);
            return true;
        }
        
        
        
    
    }

      上面的程序中两行粗体字代码就是加载选项菜单资源、上下文菜单资源的关键代码。
      从上面的程序可以看出,如果使用XML资源文件定义菜单,就像使用布局文件来定义应用程序一样,Android应用的Java代码就会简单很多,因此可维护性更好。、

      归纳起来,使用XML资源定义菜单有如下两个好处。

    • XML资源文件不仅负责定义应用界面,也负责定义菜单,这样可把所有界面相关的内容交给XML文件管理,而Java代码的功能更集中。
    • 后期更新、维护应用时,如果需要更新、维护菜单,打开、编辑XML文件即可,避免对Java文件的修改。

      运行该程序的界面如下:

      

               

  • 相关阅读:
    多态与鸭子类型
    mixin与派生
    4.9作业
    property
    继承
    封装
    《梦断代码》阅读笔记1
    阅读笔记3——《大道至简》第四、五、六章
    阅读笔记2——《大道至简》第二、三章
    阅读笔记1——《大道至简》第一章
  • 原文地址:https://www.cnblogs.com/wolipengbo/p/3398412.html
Copyright © 2020-2023  润新知