一、Android提供了一些简单的方法来为应用添加Menu菜单。
提供了三种类型应用菜单:
1、OptionsMenu:这中类型的菜单,是Android软件中的主菜单,主要提供一些功能的入口集合,通常情况下显示在软件的右上角三个点以下 的列表中(有菜单键的就不会显示三个点)
2、ContextMenu(上下文菜单):通过手指长按才会显示(当前窗体失去焦点),弹出一个浮动在界面上方的类似于对话框性质的界面,上下文菜单通常和点击的条目有关
3、PopupMenu(弹出菜单):可以在代码中设置何时显示,调用show()方法(当前窗体不会失去焦点)
二、定义Menu菜单、处理选项事件。
1、在/res/目录下新建menu文件夹,用于存储Menu XML资源文件
2、在/res/menu/下main_menu.xml菜单界面描述文件(三种菜单界面文件的定义都一样)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<!--
item 就是一个菜单项
必须设置 id, title 属性
另外的一些属性,在 ActionBar 功能中使用
id: 事件点击的判断,区分点击的是那个菜单
-->
<item
android:id="@+id/action_settings"
android:title="@string/settings"
/>
<!-- 1. 帮助;2. 点击跳转新的Activity;3. app:showAsAction="always" -->
<item
android:id="@+id/action_help"
android:title="@string/help"
app:showAsAction="always"
android:icon="@mipmap/ic_launcher"
/>
</menu>
3.菜单加载和点击事件处理
(1)OptionsMenu:
// 1. 编写菜单xml
// 2. Activity 重写方法,进行菜单的加载
// 3. Activity 重写方法,实现菜单点击的事件处理
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// MenuInflater 用于把菜单 xml 文件,加载进来,添加到 menu 中
//getMenuInflater().inflate(R.menu.main_menu, menu);
// 代码添加:
// groupId, itemId, order, title
menu.add(0, R.id.action_settings, 0, R.string.settings);
menu.add(0, R.id.action_help, 0, R.string.help);
return true;
}
/**
* OptionsMenu 菜单项点击时的事件回调
* @param item
* @return 返回 true 代表处理了点击;
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
Intent intent;
switch (itemId) {
case R.id.action_settings:
// TODO: 处理菜单点击事件
Toast.makeText(MainActivity.this, "设置被点击了", Toast.LENGTH_SHORT).show();
intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
break;
case R.id.action_help:
intent = new Intent(this, HelpActivity.class);
startActivity(intent);
break;
}
return true;
}
(2) ContextMenu: 与ListView结合使用
public class ContextMenuActivity extends AppCompatActivity {
private List<String> mStrings;
private ArrayAdapter<String> mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
mStrings = new ArrayList<>();
for (int i = 0; i < 100; i++) {
mStrings.add("Java - " + i);
}
mAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
mStrings);
ListView listView = (ListView) findViewById(R.id.help_list);
if (listView != null) {
listView.setAdapter(mAdapter);
// 设置上下文菜单的创建监听器,内部当需要上下文的时候,自动调用创建的方法
// Activity 自身就是一个监听器,可以直接使用
listView.setOnCreateContextMenuListener(this);
// 高版本支持的内容
//if(Build.VERSION.SDK_INT >= 23) {
// 可以使用版本适配,来进行特定方法的调用
//listView.setOnContextClickListener(this);
//}
}
}
// 1. 菜单XML
// 2. 重写Activity方法,加载上下文菜单
// 3. 上下文菜单点击
// 4. 给特定的控件设置上下文菜单,通常用于ListView/GridView
/**
* 创建上下文菜单,每次需要显示上下文菜单的时候,这个方法都会被调用
*
* @param menu
* @param v 需要显示上下文菜单的控件,可以根据这个控件的ID,来加载不同的菜单
* @param menuInfo
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.help_context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_copy:
// TODO: 复制
// 上下文菜单的附加信息,只有在ListView和GridView中,这个变量才可以使用
ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo();
if (menuInfo != null) {
// 如果是 ListView或者 GridView,就用下面的这个类
AdapterView.AdapterContextMenuInfo adapterMenuInfo
= (AdapterView.AdapterContextMenuInfo) menuInfo;
String s = mStrings.get(adapterMenuInfo.position);
Toast.makeText(ContextMenuActivity.this, "复制 " + s, Toast.LENGTH_SHORT).show();
}
break;
}
return true;
}
}
(3) PopupMenu:
public class PopupMenuActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
}
/**
* 点击按钮,显示一个PopupMenu
* @param view
*/
public void btnShowPopupMenu(View view) {
// 1. 创建PopupMenu 对象
// 2. 获取MenuInflater,加载菜单XML
// 3. 显示
// 4. 实现菜单的点击
// 第二个参数,代表弹出菜单在哪个控件上显示
PopupMenu popupMenu = new PopupMenu(this, view);
popupMenu
.getMenuInflater()
.inflate(R.menu.settings_popup_menu, popupMenu.getMenu());
// 设置PopupMenu的item点击处理事件
popupMenu.setOnMenuItemClickListener(this);
//设置菜单与控件的对齐方式
popupMenu.setGravity(Gravity.TOP);
popupMenu.show();
}
/**
* Item菜单点击
* @param item
* @return
*/
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_copy:
Toast.makeText(SettingsActivity.this, "PopupMenu 复制", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
三. 菜单对比
1.OptionsMenu:对应整个标题菜单和Activity功能的跳转
2.ContextMenu:对应某一个控件或者ListView的某一个Item,长按才会出来菜单,事件的处理,也是针对一项。
3.PopupMenu: 可以直接显示在指定的控件上的菜单,不需要长按这种操作方式,直接通过代码来指定显示的控件位置的。使用场景:联系人列表,点击直接出菜单的方式,新闻客户端 新闻列表部分,点击出现弹出列表,能够进行分享,转发,收藏等。