onOptionsItemSelected() 返回值的理解

首先查看官方 API 的解释:

This hook is called whenever an item in your options menu is selected. The default implementation simply returns false to have the normal processing happen (calling the item's Runnable or sending a message to its Handler as appropriate). You can use this method for any items for which you would like to do processing without those other facilities.

也就是说当点击 OptionsMenu 中的 Item 时,默认会返回 false,这个时候将会处理 item 关联的 Runnable 或发送一条 message 给它的 Handler。 为了弄清楚返回 false 时可能会发生什么做了如下测试:

  1. 测试一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.add_item:
    Toast.makeText(MainActivity.this, "Add", Toast.LENGTH_LONG).show();
    break;
    case R.id.remove_item:
    Toast.makeText(MainActivity.this, "Remove", Toast.LENGTH_LONG).show();
    item.setActionView(R.layout.progress);
    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
    item.setIntent(intent);
    Log.i(TAG, "onOptionsItemSelected: Remove");
    break;
    default:
    Toast.makeText(MainActivity.this, "re", Toast.LENGTH_LONG).show();
    }
    return true;
    }
    > 上述代码中给 item 关联了一个 Intent 用于跳转到 SecondActivity,如果返回为 true 则点击 item 时不会跳转到 SecondActivity,如果返回 false 则会跳转到 SecondActivity。

  2. 测试二
    • 创建一个 Fragment

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      public class MyFragment extends Fragment {

      @Override
      public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
      inflater.inflate(R.menu.main, menu);
      super.onCreateOptionsMenu(menu, inflater);
      }

      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case R.id.remove_item:
      Toast.makeText(getContext(), "Fragment Remove", Toast.LENGTH_LONG).show();
      break;
      default:
      Toast.makeText(getContext(), "Fragment", Toast.LENGTH_LONG).show();
      }
      return false;
      }

      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
      Bundle savedInstanceState) {
      setHasOptionsMenu(true);
      return inflater.inflate(fragment_layout, container, false);
      }
      }
      上述创建了一个自定义的 Fragment 类,并添加了 OptionMenu 的点击事件。

    • 在之前的 Activity 的布局文件中添加 Fragment

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <LinearLayout 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:orientation="vertical">

      <fragment
      android:id="@+id/fragment"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:name="com.rookieyang.demo.MyFragment"
      tools:layout="@layout/fragment_layout" />

      </LinearLayout>

    在完成上述步骤之后点击 remove 的 item,由于 Activity 中的 onOptionsItemSelected() 返回了false,导致事件没有被消费就会向下传递给 Fragment,进而执行 Fragment 中的 item 的点击事件,所以能够看到屏幕上将会显示 Fragment Remove 而不是 Remove

补:OptionMenu 的 Item 自定义的点击事件优先级要高于 onOptionsItemSelected()。