您的位置:首页 > 移动开发 > Android开发

【攻克Android (13)】Menu 菜单

2015-08-01 00:26 615 查看
[size=large]本文围绕以下三个部分展开: [/size]

[size=large]一、Menu 菜单[/size]
[size=large]二、一个案例[/size]
[size=medium]1、主界面[/size]
[size=medium]2、Options menu 选项菜单[/size]
[size=medium]3、Context menu 上下文菜单[/size]
[size=medium]4、Contextual Action Bar(CAB) 上下文操作栏[/size]
[size=medium]5、Popup menu 弹出菜单[/size]

[size=large]附 代码补充[/size]


[size=large]一、Menu 菜单[/size]

[size=medium]关于菜单:[/size]

[size=medium]3.0 开始 android 取消了实体的菜单按钮,引入了操作栏(Action Bar) [/size]

[size=medium]5.0 将操作栏更名为应用栏(App Bar),有以下四种形式的菜单:[/size]

[size=medium](1)选项菜单(Options menu)[/size]

[size=medium](2)上下文菜单(Context menu)[/size]

[size=medium](3)上下文操作栏(Contextual Action Bar)[/size]

[size=medium](4)弹出菜单(Popup menu)[/size]

[align=center][/align]

[align=center][/align]


[size=large]二、一个案例[/size]

[size=medium]1、主界面[/size]

[align=center][/align]

[size=medium](1)activity_main.xml[/size]

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

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

</RelativeLayout>


[size=medium](2)MainActivity[/size]

package com.android.menu;  

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class MainActivity extends Activity {
private ListView listView;
private String[] data = {"选项菜单(Options menu)", "上下文菜单(Context menu)", "Contextual Action Bar(CAB)", "弹出菜单(Popup menu)"};
private ArrayAdapter<String> adapter;

private Class[] items = {OptionsActivity.class, ContextActivity.class, CabActivity.class, PopupActivity.class};

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

// 设置导航图标
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);

listView = (ListView) findViewById(R.id.listView);
adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.tvItem, data);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, longid) {
startActivity(new Intent(getApplicationContext(), items[position]));
}
});
}
}


[size=medium]2、Options menu 选项菜单[/size]

[align=center][/align]

[size=medium]右上角三个菜单依次是:排序、新增、更多菜单。当点击右上角的三个点的菜单后,会出现下面3项:[/size]

[align=center][/align]

[size=medium]当点击“设置”时,界面弹出“设置操作...”:[/size]

[align=center][/align]

[size=medium]当点击排序菜单时,界面出现排序菜单:[/size]

[align=center][/align]

[size=medium]当点击“隐藏排序”时,排序菜单会隐藏不见:[/size]

[align=center][/align]

[size=medium]当再点击“显示排序”时,排序菜单会出现:[/size]

[align=center][/align]

[size=medium](1)menu_options.xml [/size]

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

<!--
item 节点:菜单一个选项
id:菜单 id (唯一)
orderInCategory:id索引值 (从小到大加载)
showAsAction:在 应用栏 显示方式
title:菜单文本
-->
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>

<item
android:id="@+id/action_exit"
android:orderInCategory="101"
android:showAsAction="never"
android:title="@string/action_exit"/>

<!-- id: 标识符 -->
<!-- icon: 图标 -->
<!-- title: (无图标时)显示的文字 -->
<!-- showAsAction: 是否显示在操作栏 -->
<!-- visible: 是否可见,默认 true -->
<!-- enabled: 是否可用,默认 true-->
<!-- orderInCategory: 序号,数值越小越靠前 -->
<item
android:id="@+id/action_new"
android:enabled="true"
android:icon="@drawable/ic_action_new"
android:orderInCategory="102"
android:showAsAction="always"
android:title="@string/action_new"
android:visible="true" />

<!-- checkableBehavior: single(单选)、all(多选)、none(不可选) -->
<!-- checkable: 是否可选 -->
<!-- checked: 是否选中 -->
<item
android:id="@+id/action_sort"
android:icon="@drawable/ic_action_sort_by_size"
android:showAsAction="ifRoom"
android:title="排序">

<menu>
<group
android:id="@+id/group_sort"
android:checkableBehavior="single">
<item
android:id="@+id/action_sort_abc"
android:checked="true"
android:title="字母顺序" />
<item
android:id="@+id/action_sort_desc"
android:title="从大到小" />
<item
android:id="@+id/action_sort_asc"
android:title="从小到大" />
<item
android:id="@+id/action_sort_time"
android:title="最后修改" />
</group>
</menu>
</item>

<item
android:id="@+id/action_hide_sort"
android:showAsAction="never"
android:orderInCategory="99"
android:title="隐藏排序" />
</menu>


[size=medium](2)OptionsActivity[/size]

package com.android.menu;  

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

/**
* 选项菜单 Options Menu
*/
public class OptionsActivity extends Activity {
private boolean isHideSort = false;

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

/**
* 1. 创建 选项菜单
*
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 填充菜单
this.getMenuInflater().inflate(R.menu.menu_options, menu);
return true;
}

/**
* 2. 预处理 选项菜单
*
* @param menu
* @return
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// 修改菜单项的标题
menu.findItem(R.id.action_hide_sort).setTitle(
isHideSort ? "显示排序" : "隐藏排序");
// 设置菜单是否可见(开始是可见的)
menu.findItem(R.id.action_sort).setVisible(!isHideSort);
// 设置组可见
menu.setGroupVisible(R.id.group_sort, !isHideSort);
// 设置组是否可选
menu.setGroupCheckable(R.id.group_sort, true, true);
// 设置组是否可用
menu.setGroupEnabled(R.id.group_sort, true);

return true;
}

/**
* 3. 选中 选项菜单的事件
*
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// 设置菜单项的视觉行为
if (R.id.group_sort == item.getGroupId()) {
// 该组的 checkableBehavior 为单选
item.setChecked(true);
return true;
}

String text = "";
switch (item.getItemId()) {
case R.id.action_settings:
text = "设置操作...";
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
return true;
case R.id.action_exit:
// 关闭
this.finish();
return true;
case R.id.action_hide_sort:
isHideSort = !isHideSort;
// 让菜单重新创建
// 会调用 onCreateOptionMenu 和 onPrepareOptionsMenu 方法
invalidateOptionsMenu();
return true;
}
return super.onOptionsItemSelected(item);
}

/**
* 4. 关闭选项菜单
*/
@Override
public void closeOptionsMenu() {
super.closeOptionsMenu();
}
}


[size=medium]3、Context menu 上下文菜单[/size]

[align=center][/align]

[align=center][/align]

[align=center][/align]

[align=center][/align]

[size=medium](1)activity_context.xml :[/size]

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_he 20000 ight="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.android.menu.ContextActivity">

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

</RelativeLayout>


[size=medium](2)menu_context.xml :[/size]

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

<item android:id="@+id/action_copy"
android:title="复制"/>

<item android:id="@+id/action_paste"
android:title="粘贴"/>

<item android:id="@+id/action_delete"
android:title="删除"/>
</menu>


[size=medium](3)ContextActivity :[/size]

package com.android.menu;  

import android.app.Activity;
import android.os.Bundle;
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;

/**
* 上下文菜单 Context Menu
*/
public class ContextActivity extends Activity {
private ListView listView;
private List<String> data = new ArrayList<>();
private ArrayAdapter<String> adapter;

private int position;

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

for (int i = 0; i < 30; i++) {
data.add("数据项 " + i);
}

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

// 3. 注册上下文菜单,调用 onCreateContextMenu
registerForContextMenu(listView);

// 3.1 注销上下文菜单(一般不会用:既然用了上下文菜单,就不会去注销)
//unregisterForContextMenu(listView);
}

/**
* 1. 创建 上下文菜单
*
* @param menu
* @param v
* @param menuInfo
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
this.getMenuInflater().inflate(R.menu.menu_context, menu);

// 设置图标和文本
menu.setHeaderIcon(android.R.drawable.ic_menu_edit);
menu.setHeaderTitle("操作:");

// 菜单信息:targetView、position,id
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) menuInfo;

// 列表中触发长按事件(弹出菜单)的位置
position = info.position;
}

/**
* 2. 上下文菜单 选项事件
*
* @param item
* @return
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_copy:
doOperator("复制");
break;
case R.id.action_paste:
doOperator("粘贴");
break;
case R.id.action_delete:
doOperator("删除");
break;
}
return true;
}

private void doOperator(String text) {
// 显示被点击按钮下标的值
Toast.makeText(this, text + " " + data.get(position), Toast.LENGTH_SHORT).show();
}

/**
* 4. 关闭 上下文菜单
*
* @param menu
*/
@Override
public void onContextMenuClosed(Menu menu) {
super.onContextMenuClosed(menu);
}
}


[size=medium]4、Contextual Action Bar(CAB) 上下文操作栏[/size]

[align=center][/align]

[align=center][/align]

[align=center][/align]

[size=medium](1)activity_cab.xml[/size]

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.android.menu.CabActivity">

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

</RelativeLayout>


[size=medium](2)menu_cab.xml[/size]

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

<item android:id="@+id/action_cab_copy"
android:title="复制"/>

<item android:id="@+id/action_cab_delete"
android:title="删除"/>

</menu>


[size=medium](3)[/size]

package com.android.menu;  

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;


public class CabActivity extends Activity {
private ListView listView;
private ArrayList<String> data = new ArrayList<String>();
private ArrayAdapter<String> adapter;

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

for (int i = 0; i < 30; i++) {
data.add("数据项 " + i);
}

listView = (ListView) findViewById(R.id.listView_cab);

// 模版需要有选中状态(activated)
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
data);

listView.setAdapter(adapter);

// 设置选择模式
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

// 设置多选监听器
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
// 2. 获得选中的总数
int count = listView.getCheckedItemCount();
// 2.1 设置标题 (显示有几个选中了)
mode.setTitle(String.valueOf(count));
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 1. 创建菜单
getMenuInflater().inflate(R.menu.menu_cab, menu);
return true;
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

// 3.
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// 获得选中的多项【稀疏数组】
SparseBooleanArray array = listView.getCheckedItemPositions();
switch (item.getItemId()) {
case R.id.action_cab_copy:
// {2=true, 4=true, 5=true}................
Log.v("MENU", array.toString() + "................");
//适用于有 ID 的数据
//long[] ids = listView.getCheckedItemIds();
break;
case R.id.action_cab_delete:
for (int i = array.size() - 1; i > -1; i--) {
// {2=true, 4=true, 5=true} 分割开
// 获得选中的下标
int position = array.keyAt(i);
// 删除数据中的指定元素(之前被选中的元素)
data.remove(position);
}
break;
}
//通知视图改变
adapter.notifyDataSetChanged();

// 结束CAB模式,调用 onDestoryActionMode 方法
mode.finish();
return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {

}
});
}


}


[size=medium]5、Popup menu 弹出菜单[/size]

[align=center][/align]

[size=medium](1)activity_popup.xml :[/size]

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.android.menu.PopupActivity">

<Button
android:id="@+id/button_popupMenu"
style="@android:style/Widget.DeviceDefault.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:drawablePadding="8dp"
android:drawableRight="@drawable/ic_more_vert_grey600_16dp"
android:onClick="onClick"/>

</RelativeLayout>


[size=medium](2)menu_popup.xml :[/size]

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

<item
android:id="@+id/action_pop_edit"
android:title="编辑"/>

<item
android:id="@+id/action_pop_remove"
android:title="删除"/>

</menu>


[size=medium](3)PopupActivity :[/size]

package com.android.menu;  

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;


public class PopupActivity extends Activity {

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

public void onClick(View view) {
// 创建弹出菜单
// 参数一:上下文
// 参数二:菜单的锚
PopupMenu menu = new PopupMenu(this, view);

// 加载菜单文件
menu.inflate(R.menu.menu_popup);

// 添加菜单项点击监听器
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_pop_edit:
Log.v("MENU", "修改......");
break;
case R.id.action_pop_remove:
Log.v("MENU", "删除......");
break;
}
return true;
}
});

// 添加菜单消失时的监听器【点击菜单项或其他区域,菜单会消失】
menu.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu menu) {

}
});

// 显示菜单
menu.show();
}
}



[size=large]附 代码补充[/size]

[size=medium]1. style.xml(v21) :[/size]

<?xml version="1.0" encoding="utf-8"?>  
<resources>

<style name="AppTheme" parent="android:Theme.Material.Light">
<item name="android:colorPrimaryDark">@android:color/holo_blue_dark</item>
<item name="android:colorPrimary">@android:color/holo_blue_light</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>


[size=medium]2. strings.xml :[/size]

<resources>  
<string name="app_name">Menu</string>

<string name="title_activity_options">选项菜单</string>
<string name="title_activity_context">上下文菜单</string>
<string name="title_activity_popup">弹出式菜单</string>
<string name="title_activity_cab">上下文操作栏</string>

<string name="action_settings">设置</string>
<string name="action_exit">退出</string>
<string name="action_new">新建</string>

</resources>


[size=medium]3. AndroidManifest.xml :[/size]

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

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".OptionsActivity"
android:label="@string/title_activity_options"
android:parentActivityName=".MainActivity"/>
<activity
android:name=".ContextActivity"
android:label="@string/title_activity_context"
android:parentActivityName=".MainActivity"/>
<activity
android:name=".CabActivity"
android:label="@string/title_activity_cab"
android:parentActivityName=".MainActivity"/>
<activity
android:name=".PopupActivity"
android:label="@string/title_activity_popup"
android:parentActivityName=".MainActivity"/>
</application>
</manifest>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: