选项菜单
在res/menu目录下定义选项菜单
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!--
showAsAction属性用于指定菜单选项是显示在操作栏上,还是隐藏到溢出菜单中。该属性当前设置为ifRoom和withText的一个组合值。
因此,只要空间足够,菜单项图标及其文字都会显示在操作栏上。如空间仅够显示菜单图标,则不会显示文字描述。如空间大小不够显示任何一项,
则菜单项会被转移隐藏到溢出菜单中。
属性showAsAction还有另外两个可选值:always和never。不推荐使用always,应尽量使用更为方便的ifRoom属性值,让操作系统
决定如何显示菜单项。对于那些很少用到的菜单项,使用never是个不错的选择。总的来说,为避免看到混乱的用户界面,只应将用户经常使用的
菜单放置在操作栏上。
注意,虽然android:showAsAction属性是在API11级引入的,但Android Lint 并没有报出兼容性问题。不同于java代码,XML
属性是不需要注解保护的。在早期API级别的设备上,后期新版本引入的XML属性会被自动忽略。
-->
<item
android:id="@+id/menu_item_new_crime"
android:icon="@android:drawable/ic_menu_add"
android:showAsAction="ifRoom|withText"
android:title="@string/new_crime"/>
<item
android:id="@+id/menu_item_show_subtitle"
android:showAsAction="ifRoom"
android:title="@string/show_subtitle"/>
</menu>
创建选项菜单
/**
* 创建选项菜单 Fragment的onCreateOptionsMenu(...)方法是由FragmentManager负责调用的。因此,
* 当activity接收到来自操作系统的
* Fragment的onCreateOptionsMenu(...)方法回调请求时,我们必须明确告诉FragmentManager
* :其管理的fragment应接收
* onCreateOptionsMenu(...)方法的调用指令。要通知FragmentManager,需在Fragmnet
* .onCreate(...)中调用以下方法:
* setHasOptionsMenu(true),通知FragmentManager:Fragment需接收选项菜单方法回调。
*/
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime_list, menu);
MenuItem showSubTitle = menu.findItem(R.id.menu_item_show_subtitle);
if (mSubTitleVisible && showSubTitle != null)
showSubTitle.setTitle(R.string.hide_subtitle);
}
响应菜单项选择事件
/**
* 响应菜单项选择事件
*/
@TargetApi(11)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new_crime:
Crime crime = new Crime();
CrimeLab.get(getActivity()).addCrime(crime);
Intent intent = new Intent(getActivity(), CrimePagerActivity.class);
intent.putExtra(CrimeFragment.EXTRA_CRIME_ID, crime.getId());
startActivity(intent);
return true;// 返回true值以表明已完成菜单项选择需要处理的全部任务
case R.id.menu_item_show_subtitle:
/**
* setSubtitle(...)方法是API11
* 级,却没有置于版本条件判断中。由于R.id.menu_item_show_subtitle 只会出现在API
* 11级以及以上的设备中出现,故不需要。
*/
if (getActivity().getActionBar().getSubtitle() == null) {
mSubTitleVisible = true;
getActivity().getActionBar().setSubtitle(R.string.subtitle);
item.setTitle(R.string.hide_subtitle);
} else {
mSubTitleVisible = false;
getActivity().getActionBar().setSubtitle(null);
item.setTitle(R.string.show_subtitle);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
运行结果如下:
菜单项标题怎么没有显示?大多数设备在竖直模式下屏幕空间有限,因此,应用的操作栏上只够显示菜单项图标。长按操作栏上的菜单图标,可弹出菜单标题。如下图:
水平模式下操作栏上有足够空间显示菜单项图标和菜单标题,如下图:
启用应用图标向上导航按钮的功能
/**
* 为启用应用图标向上导航按钮的功能,并在fragment视图上显示向左的图标,必须调用以下方法,该方法来自API 11级。
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if(NavUtils.getParentActivityName(getActivity()) != null)
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home://无需在XML文件中定义或生成应用图标菜单项。它已具有现成的资源ID
/**
* 方法一:FLAG_ACTIVITY_CLEAR_TOP指示Android在回退栈中寻找指定activity的存在实例,
* 若存在,则弹出占中所有在指定activity之上的所有其他activity,让指定activity出现在
* 栈顶,从而显示在屏幕上。
*/
// Intent intent = new Intent(getActivity(), CrimeListActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// startActivity(intent);
/**
* 方法二:先在AndroidManifest.xml文件中对当前CrimePagerActivity添加新的meta-data属性,
* 指定CrimePagerActivity的父类为CrimeListActivity。再调用以下代码,判断元数据中是否指定了
* 父类。如有指定父类,则调用NavUtils.navigateUpFromSameTask(Activity)方法,导航至父Activity界面。
*/
/**
* 为什么使用NavUtils类要好于手动启动activity?首先,NavUtils类的实现代码既简洁又优雅。其次,使用NavUtils类也可以实现
* 在AndroidManifest.xml配置文件中同一管理activity间的关系。如果activity间的关系发生改变,无需费力地去修改java代码,
* 我们只需简单修改配置文件中的一行代码即可。除此之外,使用NavUtils类还可保持层级关系处理与fragment的代码相分离。这样,即使在
* 各个具有不同父类的activity中使用同一fragment,fragment依然可以正常工作。
*/
if(NavUtils.getParentActivityName(getActivity()) != null){
NavUtils.navigateUpFromSameTask(getActivity());
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
<activity
android:name="com.huangfei.criminalintent.CrimePagerActivity"
android:label="@string/app_name" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".CrimeListActivity" />
<!-- 指定CrimePagerActivity的父类为CrimeListActivity -->
</activity>