一、菜单类型
1. Action菜单
MENU按键弹出菜单,如果是Android3.0之后,则是ActionBar选项菜单。
onCreateOptionsMenu
onOptionsItemSelected
2. 上下文菜单
上下文菜单,长按View时显现的菜单。
onCreate中:registerForContextMenu
onCreateContextMenu
onContextItemSelected
3. 弹出菜单PopupMenu
依托于指定的View,依据空间大小显示在View的上方或下方。
二、菜单创建(手工创建、XML创建)
手工创建,如:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 0, "item1");
menu.add(0, 2, 0, "item2");
MenuItem item = menu.getItem(0);
item.setCheckable(true);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
XML创建:
res/menu中新建:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:id="@+id/group1" android:checkableBehavior="single">
<item android:id="@+id/popup1" android:title="@string/work"></item>
<item android:id="@+id/popup2" android:title="@string/home"></item>
<item android:id="@+id/popup3" android:title="@string/personal"></item>
</group>
</menu>
对一中所述的ActionBar选项菜单,实验图示如下:
布局界面, activity_main.xml:
<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" >
<Button
android:id="@+id/btn_context"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:text="@string/context_menu" />
<Button
android:id="@+id/btn_popup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn_context"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="@string/popup_menu" />
<TextView
android:id="@+id/text_context"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/btn_context"
android:layout_alignLeft="@+id/btn_popup"
android:layout_marginBottom="47dp"
android:layout_marginLeft="37dp"
android:text="@string/text_context" />
</RelativeLayout>
主Activity, MainActivity.java:
菜单项响应顺序: onMenuItemSelected -> onOptionItemSelected/onContextItemSelected
package com.example.menutest;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.SearchView;
import android.widget.ShareActionProvider;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.SearchView.OnQueryTextListener;
public class MainActivity extends Activity implements OnQueryTextListener {
SearchView mSearchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button)findViewById(R.id.btn_context);
registerForContextMenu(button); // 注册上下文菜单
button.setOnClickListener(new Button.OnClickListener() { // 按钮单击事件
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "Click button", Toast.LENGTH_SHORT).show();
}
});
TextView tv = (TextView)findViewById(R.id.text_context);
registerForContextMenu(tv); // 注册上下文菜单
final Button popupButton = (Button)findViewById(R.id.btn_popup);
popupButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showPopup(popupButton);
}
});
}
private Intent createShareIntent()
{
// 发送文本信息
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra("sms_body", "This message is from share");
return shareIntent;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.share);
ShareActionProvider actionProvider = (ShareActionProvider)item.getActionProvider();
// 设置默认的共享文件名: public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
actionProvider.setShareHistoryFileName(ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME);
// 设置共享意图
actionProvider.setShareIntent(createShareIntent());
mSearchView = (SearchView)menu.findItem(R.id.search).getActionView();
// 注册搜索输入栏的事件监听器,来自于实现接口:android.widget.SearchView.OnQueryTextListener
// 事件回调方法为:onQueryTextSubmit()开始搜索事件;onQueryTextChange()文本改变事件
mSearchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "Option Menu Item Selected: " + item.getTitle(), Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
// Share, Search的点击事件由各自的onPerformDefaultAction所响应
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "Menu Item Selected: " + featureId + ": " + item.getTitle(), Toast.LENGTH_SHORT).show();
return super.onMenuItemSelected(featureId, item);
}
@Override
public boolean onQueryTextChange(String arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
Toast toast = Toast.makeText(this, "Searching " + arg0, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
return true;
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "Context Menu item Selected: " + item.getTitle(), Toast.LENGTH_SHORT).show();
return super.onContextItemSelected(item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.context_menu, menu);
menu.setHeaderTitle("网络");
super.onCreateContextMenu(menu, v, menuInfo);
}
private void showPopup(View v)
{
PopupMenu popup = new PopupMenu(this, v);
popup.inflate(R.menu.popup_menu);
popup.show();
popup.getMenu().getItem(0).setChecked(true);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(MainActivity.this, "Popup Menu clicked: " + item.getTitle(), Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
ActionBar菜单, main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 存在Menu键: Android 3.0以上则显示在ActionBar, 溢出菜单通过点击Menu键显示
Android 3.0之前,全部显示在Menu键中 -->
<!-- 不存在Menu键: 显示在ActionBar中, 溢出菜单为三个点的菜单 -->
<!-- 在ActionBar空间充足的情况下显示 -->
<item
android:id="@+id/edit"
android:showAsAction="ifRoom"
android:title="@string/edit"
android:icon="@android:drawable/ic_menu_edit"
/>
<!-- Search和Share应该都设置为always因为放入溢出菜单中不可用 -->
<item
android:id="@+id/search"
android:showAsAction="always"
android:title="@string/search"
android:icon="@android:drawable/ic_menu_search"
android:actionViewClass="android.widget.SearchView" />
<item
android:id="@+id/share"
android:showAsAction="always"
android:title="@string/share"
android:icon="@android:drawable/ic_menu_share"
android:actionProviderClass="android.widget.ShareActionProvider" />
<!-- 显示在三个点的溢出菜单(overflow menu)中 -->
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
上下文菜单,context_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:id="@+id/context_group" android:menuCategory="container">
<item android:id="@+id/item_work" android:title="@string/work"></item>
<item android:id="@+id/item_personal" android:title="@string/personal"></item>
<item android:id="@+id/item_home" android:title="@string/home"></item>
</group>
</menu>
弹出菜单, popup_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:id="@+id/group1" android:checkableBehavior="single">
<item android:id="@+id/popup1" android:title="@string/work"></item>
<item android:id="@+id/popup2" android:title="@string/home"></item>
<item android:id="@+id/popup3" android:title="@string/personal"></item>
</group>
</menu>
字符串定义, strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MenuTest</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="search">Search</string>
<string name="share">Share</string>
<string name="edit">Edit</string>
<string name="context_menu">长按我,显示上下文菜单</string>
<string name="popup_menu">单击我,显示弹出菜单</string>
<string name="home">家庭</string>
<string name="work">工作</string>
<string name="personal">个人</string>
<string name="text_context">Text Context Menu</string>
</resources>