[android](学习笔记7)为应用程序添加选项菜单

1 在xml文件中定义选项菜单:

  创建res/menu目录,并添加xml文件:选择New-Android XML File。选择Menu文件资源类型;

  打开新建的xml文件,切换到xml编辑视图,添加新的item元素:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/menu_item_new_crime"
        android:icon="@android:drawable/ic_menu_add"
        android:title="@string/new_crime"
        android:showAsAction="ifRoom|withText" />
</menu>

  为item新建资源id,在后面的响应代码中,会用到该id。showAsAction属性用于指定菜单项是显示在操作栏上,还是隐藏在溢出菜单中。选择ifRoom和withText组合值,表明如果空间足够,菜单项和文字标题都会显示,如果空间只够显示图标,则文字标题不会显示。如何访问溢出菜单,取决于具体设备。

2 创建选项菜单:

  在需要选项菜单时,Android会调用activity的onCreateOptionMenu方法。不过Fragment也有一套自己的选项菜单回调函数:

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
public boolean onOptionsItemSelected(MenuItem item)

  首先在Fragment类中覆盖onCreateOptionsMenu方法,通过参数inflater创建菜单:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // 该方法由托管activity的FragmentManager负责调用
    // TODO Auto-generated method stub
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.fragment_crime_list, menu);
}

  调用超类的onCreateOptionsMenu方法属于编程规范,尽管它内部什么也不做。为了告知托管activity的FragmentManager自己有选项菜单,需要调用setHasOptionsMenu方法:

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true); // onCreateOptionsMenu方法由托管activity的FragmentManager负责调用,
                             // 需要借助setHasOptionsMenu方法告知FragmentManager
    getActivity().setTitle(R.string.crimes_title);  // getActivity()返回托管activity
                                // CrimeListFragment要显示CrimeLab中的Crime列表,需要先获取CrimeLab单例对象,进而获取其中的列表
    mCrimes = CrimeLab.get(getActivity()).getCrimes();
        
    CrimeAdapter adapter = new CrimeAdapter(mCrimes);
    // listview <--> adapter <--> mCrimes
    setListAdapter(adapter); // 为CrimeListFragment内置ListView设置adapter
}

3 响应菜单选择:

  若要响应选项菜单的选择,需要覆盖onOptionsItemSelected:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch(item.getItemId()) {
    case R.id.menu_item_new_crime: {
    // TODO: Add your code...
    return true; } default: return super.onOptionsItemSelected(item); } }

  其中,R.id.menu_item_new_crime就是一开始创建的选项菜单项的id,返回true表明已经处理完所有的响应任务,如果item不是自己关系的,可以走default分支,让超类来处理。

 

附加内容:

如何为应用程序添加层级式导航?

现在很多应用程序,都在选项菜单的地方有一个向上的层级导航按钮,下面给出最一般的实现思路。

1 启用应用图标向上导航按钮的功能:

  在Fragment.onCreateView方法调用setDisplayHomeAsUpEnable方法,设置fragment的属性。

@TargetApi(11)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    // step4
    // TODO Auto-generated method stub
    View v = inflater.inflate(R.layout.fragment_crime, parent, false);
    // 启用向上导航按钮
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        if (NavUtils.getParentActivityName(getActivity()) != null) {
                getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
        }
}

  这时,应用程序图标上会显示向左的图标,但点击该按钮,无响应。

2 响应向上按钮:

  覆盖Fragment.onOptionsItemSelected方法:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home: {
        if (NavUtils.getParentActivityName(getActivity()) != null) { // 首先判断是否有父activity,有则完成跳转,这种父子关系通过Manifest注册
          NavUtils.navigateUpFromSameTask(getActivity());
        }
        return true;
    }
    default: {
        return super.onOptionsItemSelected(item);
    }
    }
}

  这里借助的是NavUtils类完成从一个activity跳转到另一个activity的导航功能。这种源到目的的关系是通过Manifest文件来注册的,例如,从Activity_A跳转到Activity_B,可以在Manifest中注册:

<activity android:name=".Activity_A"
      android:label="@string/app_name" >
          <meta-data android:name="android.support.PARENT_ACTIVITY"
            android:value=".Activity_B"/>
</activity>

 

posted @ 2015-05-24 17:03  跑调的心跳  阅读(542)  评论(0编辑  收藏  举报