【起航计划 023】2015 起航计划 Android APIDemo的魔鬼步伐 22 App->Menu->Inflate from XML 使用xml资源展示菜单

本例MenuInflateFromXml.java演示了如何从Menu 资源(XML 定义)展开菜单项。这个例子的onCreate 采用了使用代码来创建Activity 界面的方法 而通常的方法是采用Layout资源的方法。如果你有兴趣了解一下如何使用代码创建UI,可以参考本例的onCreate方法,但这不是本例的演示目的。

        // 1.创建LinearLayout布局 Create a simple layout     LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        // 2.创建一个spinner Create the spinner to allow the user to choose a menu XML
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, sMenuExampleNames);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSpinner = new Spinner(this);
        // When programmatically creating views, make sure to set an ID
        // so it will automatically save its instance state
        mSpinner.setId(R.id.spinner);
        mSpinner.setAdapter(adapter);
        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                invalidateOptionsMenu();
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        // 3.添加spinner到布局中Add the spinner
        layout.addView(mSpinner,
                new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT));

        // 4.创建一个TextView Create help text
        mInstructionsText = new TextView(this);
        mInstructionsText.setText(getResources().getString(
                R.string.menu_from_xml_instructions_press_menu));

        // 5.添加TextView到布局中 Add the help, make it look decent
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        lp.setMargins(10, 10, 10, 10);
        layout.addView(mInstructionsText, lp);

        // 6.Set the layout as our content view
        setContentView(layout);

使用XML 菜单资源来展开菜单的一般步骤是

1. 在/res/menu目录下定义菜单资源,本例中定义了10种不同风格的菜单项:”Title only”, “Title and Icon”, “Submenu”, “Groups”,”Checkable”, “Shortcuts”, “Order”, “Category and Order”,”Visible”, “Disabled”。

最简单的Menu资源定义如下:只包括id 和title 定义。

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/jump"
        android:title="@string/jump" />

    <item android:id="@+id/dive"
        android:title="@string/dive" />

</menu>

2. 展开菜单资源,Android支持两大类菜单Option Menu(主菜单),Context Menu  (上下文相关菜单)。本例使用Option Menu ,可以在public boolean onCreateOptionsMenu(Menu menu) 方法中使用MenuInflater 展开菜单资源:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Hold on to this
        mMenu = menu;

        // Inflate the currently selected menu XML resource.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(sMenuExampleResources[mSpinner.getSelectedItemPosition()], menu);

        // Change instructions
        mInstructionsText.setText(getResources().getString(
                R.string.menu_from_xml_instructions_go_back));

        return true;
    }

3. 为菜单添加处理事件的方法。

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // For "Title only": Examples of matching an ID with one assigned in
            //                   the XML
            case R.id.jump:
                Toast.makeText(this, "Jump up in the air!", Toast.LENGTH_SHORT).show();
                invalidateOptionsMenu();  //调用这个方法,原来的菜单项将无效
                return true;

            case R.id.dive:
                Toast.makeText(this, "Dive into the water!", Toast.LENGTH_SHORT).show();
                return true;

            // For "Groups": Toggle visibility of grouped menu items with
            //               nongrouped menu items
            case R.id.browser_visibility:
                // The refresh item is part of the browser group
                final boolean shouldShowBrowser = !mMenu.findItem(R.id.refresh).isVisible();
                mMenu.setGroupVisible(R.id.browser, shouldShowBrowser);
                break;

            case R.id.email_visibility:
                // The reply item is part of the email group
                final boolean shouldShowEmail = !mMenu.findItem(R.id.reply).isVisible();
                mMenu.setGroupVisible(R.id.email, shouldShowEmail);
                break;

            // Generic catch all for all the other menu resources
            default:
                // Don‘t toast text when a submenu is clicked
                if (!item.hasSubMenu()) {
                    Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
                    return true;
                }
                break;
        }

        return false;
    }

但用户选择某个菜单时将触发onOptionsItemSelected 事件,参数item为用户选择的Menu Item,可以根据Menu 的 Id来实现菜单项对应的操作。

本例菜单使用10种不同的风格,基本使用方法是都是一样的,不同是定义在XML item的属性。

Title only

最简单的菜单,菜单只含有文本描述。

Title and Icon

菜单含有文字和图标。增加android:icon属性。

    <item android:id="@+id/happy"
        android:title="Happy"
        android:icon="@drawable/stat_happy" />

Sub Menu

尽管在手机使用多层菜单的可能性不大,但如果想使用sub Menu的话,Android 也可以支持多次菜单,这是通过嵌套定义Menu Item的方法来实现的:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:title="Normal 1" />

    <item android:id="@+id/submenu"
        android:title="Emotions">

        <menu>        

            <item android:id="@+id/happy"
                android:title="Happy"
                android:icon="@drawable/stat_happy" />

            <item android:id="@+id/neutral"
                android:title="Neutral"
                android:icon="@drawable/stat_neutral" />

            <item android:id="@+id/sad"
                android:title="Sad"
                android:icon="@drawable/stat_sad" />

        </menu>

    </item>

    <item android:title="Normal 2" />

</menu>

Groups

Menu定义上可以将一些相关的菜单定义为一个组,同组的菜单项可以定义一些相同的属性,比如可以使用setGroupVisible设置组内所有成员是否可见,setGroupEnabled可以组内所有成员是否有效等。组的定义是使用group来定义:

    <group android:id="@+id/browser">

        <item android:id="@+id/refresh"
            android:title="@string/browser_refresh" />

        <item android:id="@+id/bookmark"
            android:title="@string/browser_bookmark" />

    </group>

组可以定义id,比如想将菜单组的可见性可以使用:

                // The refresh item is part of the browser group
                final boolean shouldShowBrowser = !mMenu.findItem(R.id.refresh).isVisible();
                mMenu.setGroupVisible(R.id.browser, shouldShowBrowser);

Checkable

对应定义了组的Menu Item可以定义组的checkable ,组内item可以继承组的checkable 属性,不在组内的item可以单独定义自己的checkable属性,定义了checkable属性的菜单将会以Check button或是Radio Button的风格显示:

checkable 定义了四种不同风格的checkableBehavior:

    <item android:title="None">
        <menu>
            <!-- The none checkableBehavior is default, but we explicitly show it here. -->
            <group android:id="@+id/noncheckable_group"
                    android:checkableBehavior="none">
                <!-- Notice how these items inherit from the group. -->
                <item android:id="@+id/noncheckable_item_1"
                        android:title="@string/item_1" />
                <item android:id="@+id/noncheckable_item_2"
                        android:title="@string/item_2" />
                <item android:id="@+id/noncheckable_item_3"
                        android:title="@string/item_3" />
            </group>
        </menu>
    </item>

    <item android:title="All">
        <menu>
            <group android:id="@+id/checkable_group"
                    android:checkableBehavior="all">
                <!-- Notice how these items inherit from the group. -->
                <item android:id="@+id/checkable_item_1"
                        android:title="@string/item_1" />
                <item android:id="@+id/checkable_item_2"
                        android:title="@string/item_2"
                        android:checked="true" />
                <item android:id="@+id/checkable_item_3"
                        android:title="@string/item_3"
                        android:checked="true" />
            </group>
        </menu>
    </item>

    <item android:title="Single">
        <menu>
            <group android:id="@+id/exclusive_checkable_group"
                    android:checkableBehavior="single">
                <!-- Notice how these items inherit from the group. -->
                <item android:id="@+id/exclusive_checkable_item_1"
                        android:title="@string/item_1" />
                <item android:id="@+id/exclusive_checkable_item_2"
                        android:title="@string/item_2" />
                <item android:id="@+id/exclusive_checkable_item_3"
                        android:title="@string/item_3"
                        android:checked="true" />
            </group>
        </menu>
    </item>

    <item android:title="All without group">
        <menu>
            <!-- Notice how these items have each set. -->
            <item android:id="@+id/nongroup_checkable_item_1"
                    android:title="@string/item_1"
                    android:checkable="true" />
            <item android:id="@+id/nongroup_checkable_item_2"
                    android:title="@string/item_2"
                    android:checkable="true"
                    android:checked="true" />
            <item android:id="@+id/nongroup_checkable_item_3"
                    android:title="@string/item_3"
                    android:checkable="true"
                    android:checked="true" />
        </menu>
    </item>

Shortcuts

菜单项可以添加快捷键属性,比如按下”i”键,触发菜单项invisible_item。

    <item android:id="@+id/invisible_item"
        android:visible="false"
        android:alphabeticShortcut="i"
        android:title="Invisible item" />

在显示菜单时,由于多于6个菜单选项,h_item在按More时才会显示,但h_item定义了一个快捷键“h”,此时直接按”h”,会立即触发h_item菜单项。

Order

对应定义的菜单项,缺省显示的方法和定义的顺序一致,但可以使用android:orderInCategory属性重新定义菜单显示的属性。比如 下面定义的属性为fouth,third,second,first 而orderInCategory为3,2,1,0.则实际的菜单显示顺序如下图:

    <item android:id="@+id/fourth_item"
        android:orderInCategory="3"
        android:title="Fourth" />

    <item android:id="@+id/third_item"
        android:orderInCategory="2"
        android:title="Third" />

    <item android:id="@+id/second_item"
        android:orderInCategory="1"
        android:title="Second" />

    <item android:id="@+id/first_item"
        android:orderInCategory="0"
        android:title="First" />

Category and Order

除了缺省的category ,也可以再定义其它的次要的Category,每个Category可以分别再为每个Menu Item定义它们的android:orderInCategory,最后菜单项显示的顺序是 :按orderInCategory顺序显示缺省Category的所有菜单项,接着在按orderInCategory顺序显示次要Category中 的菜单项:比如category_order.xml有如下定义:

    <!-- This group uses the default category. -->
    <group android:id="@+id/most_used_items">

        <item android:id="@+id/last_most_item"
            android:orderInCategory="10"
            android:title="@string/last_most_often" />

        <item android:id="@+id/middle_most_item"
            android:orderInCategory="7"
            android:title="@string/middle_most_often" />

        <item android:id="@+id/first_most_item"
            android:orderInCategory="4"
            android:title="@string/first_most_often" />

    </group>

    <group android:id="@+id/least_used_items"
        android:menuCategory="secondary">

        <item android:id="@+id/last_least_item"
            android:orderInCategory="3"
            android:title="@string/last_least_often" />

        <item android:id="@+id/middle_least_item"
            android:orderInCategory="2"
            android:title="@string/middle_least_often" />

        <item android:id="@+id/first_least_item"
            android:orderInCategory="0"
            android:title="@string/first_least_often" />

    </group>

先group,再item

最后的菜单显示顺序如下:

Visible

MenuItem 具有一个android:visible属性,缺省为true,如果定义为“false”,即使在XML定义了该菜单项,最后也不会显示。

    <item android:id="@+id/visible_item"
        android:title="Visible"
        android:alphabeticShortcut="a" />

    <item android:id="@+id/hidden_item"
        android:title="Hidden"
        android:visible="false"
        android:alphabeticShortcut="b" />

Disabled

除了visable属性外,还可以指定enabled属性,enabled属性缺省为true,表示该菜单项有效,为false时,表示还菜单项无效,一般为显示为灰色。

    <item android:id="@+id/enabled_item"
        android:title="Enabled"
        android:icon="@drawable/stat_happy" />

    <item android:id="@+id/disabled_item"
        android:title="Disabled"
        android:enabled="false"
        android:icon="@drawable/stat_sad" />

时间: 2024-07-29 06:16:30

【起航计划 023】2015 起航计划 Android APIDemo的魔鬼步伐 22 App->Menu->Inflate from XML 使用xml资源展示菜单的相关文章

【起航计划 002】2015 起航计划 Android APIDemo的魔鬼步伐 01

本文链接:[起航计划 002]2015 起航计划 Android APIDemo的魔鬼步伐 01 参考链接:http://blog.csdn.net/column/details/mapdigitapidemos.html?&page=12

【起航计划 031】2015 起航计划 Android APIDemo的魔鬼步伐 30 App-&gt;Preferences-&gt;Advanced preferences 自定义preference OnPreferenceChangeListener

前篇文章Android ApiDemo示例解析(31):App->Preferences->Launching preferences 中用到了Advanced preferences 中定义的AdvancedPreferences. 本篇具体介绍AdvancedPreferences, 这个例子称为Advanced ,是因为它涉及到了自定义Preference, 并在一个工作线程中刷新某个Preference的值. Preference 为显示在PreferenceActivity (一般以

【起航计划 020】2015 起航计划 Android APIDemo的魔鬼步伐 19 App-&gt;Dialog Dialog样式

这个例子的主Activity定义在AlertDialogSamples.java 主要用来介绍类AlertDialog的用法,AlertDialog提供的功能是多样的: 显示消息给用户,并可提供一到三个按钮(OK, Cancel ,Yes ,No)用于选择或是显示警告. 显示一个列表以供用户选择,列表中可以是Radio Button  (单选),Check button (多选) 显示文本框来接受用户输入等. 创建AlertDialog一般是通过AlertDialog.Builder来构造: A

【起航计划 012】2015 起航计划 Android APIDemo的魔鬼步伐 11 App-&gt;Activity-&gt;Save &amp; Restore State onSaveInstanceState onRestoreInstanceState

Save & Restore State与之前的例子Android ApiDemo示例解析(9):App->Activity->Persistent State 实现的UI类似,但功能和实现方法稍有不同. (9)是通过Shared Preferences 和 Activity 的onPause() ,和onResume()来保持UI中 EditText 的值. 本例是通过onSaveInstanceState(Bundle savedBundle) 来实现保持UI状态. 和onPaus

【起航计划 032】2015 起航计划 Android APIDemo的魔鬼步伐 31 App-&gt;Search-&gt;Invoke Search 搜索功能 Search Dialog SearchView SearchRecentSuggestions

Search (搜索)是Android平台的一个核心功能之一,用户可以在手机搜索在线的或是本地的信息.Android平台为所有需要提供搜索或是查询功能的应用提 供了一个统一的Search Framework来帮助实现Search功能.Search Framework的UI可以有两种形式: 屏幕顶部的Search Dialog:如Google Map提供的搜索条. 可以嵌到ContentView中的SearchView,应用可以将它放在屏幕上任何地方. 不管采用那种UI,Android系统都可以通

【起航计划 003】2015 起航计划 Android APIDemo的魔鬼步伐 02

01 API Demos ApiDemos 详细介绍了Android平台主要的 API,android 5.0主要包括下图几个大类,涵盖了数百api示例: 02 入口类 ApiDemos采用分类层次显示,ApiDemo是ApiDemos的入口类,继承自ListActivity,该类的主要功能是分类列出大类,进而更进一步显示示例. ListActivity可以看做为一个含有ListView的Activity,可以不用setContentView设置布局,除非你想定制自己的List布局,这样的话,你

【起航计划 007】2015 起航计划 Android APIDemo的魔鬼步伐 06 App-&gt;Activity-&gt;Forwarding Activity启动另外一个Activity finish()方法

Android应用可以包含多个Activity,某个Activity可以启动另外的Activity. 这些Activity采用栈结构来管理,新打开的Activity叠放在当前的Activity之上,当前的Activity停止运行. 当一个Activity停止运行时,Android系统保留其停止前的状态,当用户按下“Back”按键时,栈最上的Activity从栈顶退栈,之前的Activity移到栈顶,显示在屏幕上: 有些时候,当一个Activity启动新的Activity后,不希望把当前Activ

【起航计划 005】2015 起航计划 Android APIDemo的魔鬼步伐 04 App-&gt;Activity-&gt;Custom Dialog Dialog形式的Activity,Theme的使用,Shape的使用

App->Activity->Custom Dialog 例子使用Activity 来实现自定义对话框 类CustomDialogActivity本身无任何特别之处.关键的一点是其在AndroidManifest.xml中的定义: <activity android:name=".app.CustomDialogActivity" android:label="@string/activity_custom_dialog" android:them

【起航计划 006】2015 起航计划 Android APIDemo的魔鬼步伐 05 App-&gt;Activity-&gt;Custom Title 自定义标题栏

Android UI缺省的标题栏由android:label 定义,显示在屏幕左上角,Android允许Activity自定义标题栏,使用自定义Layout重新设置标题栏,比如实现Windows Mobile 风格的标题栏. App->Activity->Custom Title 重新将Activity标题栏定义为左右两个文本框,类CustomTitle,其Layout定义R.layout.custom_title_1如下,为一左一右两个文本框: <!-- Demonstrates ho