Android - 如何在片段类中访问ActionBar的菜单项

39

我应该如何在 Fragment 中访问 ActionBar 菜单项? 我已经尝试过这个方法但是没有任何反应。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub

    switch (item.getItemId()) {
    case R.id.menu_refresh:
        Toast.makeText(getActivity().getApplicationContext(), "clicked", Toast.LENGTH_SHORT).show();
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO Auto-generated method stub
    super.onCreateOptionsMenu(menu, inflater);
}
5个回答

68

按照以下步骤进行:

  • 在你的Fragment中添加 setHasOptionsMenu(true) 方法。

  • 重写你的Fragment中的 onCreateOptionsMenu(Menu menu, MenuInflater inflater) 和 onOptionsItemSelected(MenuItem item) 方法。

  • 在你的Fragment中的 onOptionsItemSelected(MenuItem item) 方法内, 确保当菜单项操作应该在 Activity 中执行时,返回 false。

例如:

Activity

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Do Activity menu item stuff here
        return true;
    case R.id.fragment_menu_item:
        // Not implemented here
        return false;
    default:
        break;
    }

    return false;
}

碎片

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    ....
}

@Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Not implemented here
        return false;
    case R.id.fragment_menu_item:
        // Do Fragment menu item stuff here
        return true;
    default:
        break;
    }

    return false;
}

1
如果我这样做,它会在操作栏上显示双重动作项。 - Sagar Maiyad
7
复制自https://dev59.com/MGsy5IYBdhLWcg3wzBJ4#18319050。最好给予回答者以荣誉。 - Zar E Ahmer
这不是复制。https://dev59.com/MGsy5IYBdhLWcg3wzBJ4#18319050 更短更直接。不要犹豫,传递链接。 - Zon

7
在你的片段 onCreate 方法中添加 setHasOptionsMenu(true);
如果你的片段在 ViewPager 中,则具有 ViewPager 的片段也需要上述行。

6

在片段中,您不能直接访问ActionBar菜单项。 您可以在片段类的onCreateView函数中放置setHasOptionsMenu(true)。这将调用相应活动中的函数onCreateOptionsMenu(Menu menu)。

在那里,您可以访问操作栏中所有的菜单项。 您可以使用:

MenuItem item = menu.getItem(index);

您有一个使用此功能的示例:
在片段的onCreateView类中:
setHasOptionsMenu(true);

在对应的活动类中:

@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.getItem(0);
    if(condition)
        item.setVisible(true);
    else 
        item.setVisible(false);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click
    switch (item.getItemId()) {
       case R.id.action_logout:
           makeLogout();
           return  true;
       default :
           return super.onOptionsItemSelected(item);
    }

}

我想在片段中点击按钮后更改菜单中开关的状态。我该怎么做? - roghayeh hosseini
我找到了答案: 我们在片段中定义变量,然后在函数onCreateOptionsMenu中设置它。 因此,我们可以在onCreateView中使用它并更改其状态。 - roghayeh hosseini

1

我有一个建议(由于我的声誉不允许我评论),这也是原因之一,导致它对我来说无法工作。

请确保您的片段托管活动扩展了AppCompatActivity而不是FragmentActivity!

public class MainActivity extends AppCompatActivity {

}

来自Google参考文档文档的FragmentActivity:

注意:如果您想要实现一个包含操作栏的活动,您应该使用ActionBarActivity类,它是这个类的子类,因此允许您在API级别7及更高版本上使用Fragment API。

ActionBarActivity现在已被弃用,请改用AppCompatActivity。使用AppCompatActivity时,还要确保将“活动主题设置为Theme.AppCompat或类似主题”(Google文档也是如此)。

android.support.v7.app.AppCompatActivityandroid.support.v4.app.FragmentActivity类的子类(请参见AppCompatActivity ref文档)。


0

菜单项 main.xml 文件:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="dbl.contact.manager.MainActivity" >

    <item
        android:id="@+id/menu_search"
        android:actionLayout="@layout/action_bar"
        android:icon="@drawable/searchagain"
        android:orderInCategory="0"
        android:showAsAction="always"
        android:title="search"/>

</menu>

这是菜单项。自定义操作栏,如在操作栏中的edittext。您需要创建一个自定义布局。这里是自定义action_bar.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<EditText 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/inputSearch"
    android:layout_width="280dp"
    android:layout_height="40dp"
    android:cursorVisible="true"  
    android:hint="Search"
    android:imeOptions="actionDone"
    android:inputType="text"
    android:textColor="@android:color/white"
    android:textCursorDrawable="@android:color/white" />

然后在片段类中进行覆盖。只需复制并粘贴此代码。

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // TODO Add your menu entries here
        super.onCreateOptionsMenu(menu, inflater);
         getActivity().getMenuInflater().inflate(R.menu.main, menu);
         View v = (View) menu.findItem(R.id.menu_search).getActionView();
         inputSearch = (EditText)v.findViewById(R.id.inputSearch);

            inputSearch.addTextChangedListener(new TextWatcher() {

                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    // clientAdapter.getFilter().filter(s.toString());
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub
                    // ListData.this.clientAdapter.getFilter().filter(s);
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                    adapter.getFilter().filter(s.toString());

                }

            });

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接