在片段中的Android选项菜单
我正在尝试从一组片段中将选项添加到选项菜单中。
我创build了一个新的MenuFragment
类,并将其扩展为我希望包含菜单项的片段。下面是代码:
public class MenuFragment extends Fragment { MenuItem fav; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { fav = menu.add("add"); fav.setIcon(R.drawable.btn_star_big_off); } }
出于某种原因, onCreateOptionsMenu
似乎不运行。
调用超级方法:
@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); }
将日志语句放在代码中,以查看该方法是否未被调用或者菜单是否未被代码修改。
还要确保你在onCreate
中调用SetHasOptionsMenu
来通知它应该参与选项菜单处理的片段。
如果您发现onCreateOptionsMenu(Menu menu, MenuInflater inflater)
方法未被调用,请确保从Fragment的onCreate(Bundle savedInstanceState)
方法调用以下内容:
setHasOptionsMenu(true)
我有同样的问题,但我认为最好总结一下,并介绍最后一步,使其工作:
-
在你的Fragment的
onCreate(Bundle savedInstanceState)
方法中添加setHasOptionsMenu(trueonCreate(Bundle savedInstanceState)
方法。 -
在你的Fragment中覆盖
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(如果你想在Fragment的菜单中做一些不同的事情)和onOptionsItemSelected(MenuItem item)
方法。 -
在
onOptionsItemSelected(MenuItem item)
Activity的方法中,确保在菜单项目操作将在onOptionsItemSelected(MenuItem item)
Fragment的方法中实现时返回false。
一个例子:
活动
@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; }
在我的情况下,我需要一个菜单来刷新特定片段内的webview
,为此我使用:
片段 :
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // TODO Add your menu entries here inflater.inflate(R.menu.menu, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.exit: System.exit(1); break; case R.id.refresh: webView.reload(); break; } return true; }
文件menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/exit" android:title="Exit" android:icon="@drawable/ic_action_cancel" /> <item android:id="@+id/refresh" android:title="Refresh" android:icon="@drawable/ic_action_refresh" /> </menu>
在menu.xml
你应该添加所有的菜单项。 然后,您可以隐藏您在初始加载时不想看到的项目。
menu.xml文件
<item android:id="@+id/action_newItem" android:icon="@drawable/action_newItem" android:showAsAction="never" android:visible="false" android:title="@string/action_newItem"/>
在onCreate()方法中添加setHasOptionsMenu(true)
来调用Fragment类中的菜单项。
FragmentClass.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }
你不需要重写你的片段类中的onCreateOptionsMenu
。 通过覆盖Fragment中的onPrepareOptionsMenu
方法,可以更改菜单项(Add / remoev)。
@Override public void onPrepareOptionsMenu(Menu menu) { menu.findItem(R.id.action_newItem).setVisible(true); super.onPrepareOptionsMenu(menu); }
在充气菜单之前,您需要使用menu.clear()。
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); inflater.inflate(R.menu.menu, menu); super.onCreateOptionsMenu(menu, inflater); }
和
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }
我有同样的问题,我的片段是ViewPager的页面。 发生这种情况的原因是,在实例化FragmentPagerAdapter时,我使用的是儿童片段pipe理器,而不是活动支持片段pipe理器。
如果你想添加你的菜单自定义
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_custom, menu); }
菜单文件:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/play" android:titleCondensed="Speak" android:showAsAction="always" android:title="Speak" android:icon="@drawable/ic_play"> </item> <item android:id="@+id/pause" android:titleCondensed="Stop" android:title="Stop" android:showAsAction="always" android:icon="@drawable/ic_pause"> </item> </menu>
活动代码:
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.speak_menu_history, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.play: Toast.makeText(getApplicationContext(), "speaking....", Toast.LENGTH_LONG).show(); return false; case R.id.pause: Toast.makeText(getApplicationContext(), "stopping....", Toast.LENGTH_LONG).show(); return false; default: break; } return false; }
片段代码:
@Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.play: text = page.getText().toString(); speakOut(text); // Do Activity menu item stuff here return true; case R.id.pause: speakOf(); // Not implemented here return true; default: break; } return false; }
我的问题稍有不同。 我做了一切正确的。 但是,我为inheritance这个片段的活动inheritance了错误的类。
所以要清楚的是,如果你正在覆盖片段中的onCreateOptionsMenu(Menu menu, MenuInflater inflater)
,请确保你的活动类承载这个片段inheritanceandroid.support.v7.app.ActionBarActivity
(如果你想支持下面的API 11级)。
我inheritance了android.support.v4.app.FragmentActivity
以支持11以下的API级别。
有一件事我会补充到这和它不适合我的原因。
这与Napster的回答相似。
-
确保你的片段的托pipe活动扩展
AppCompatActivity
,而不是FragmentActivity
!public class MainActivity extends AppCompatActivity { }
从Google参考文档的FragmentActivity:
注意:如果要实现包含操作栏的活动,则应该使用ActionBarActivity类,该类是此类的子类,因此允许在API级别7和更高级别上使用Fragment API。
-
要更新Napster的答案 –
ActionBarActivity
现在被弃用,请改用AppCompatActivity
。 -
在使用
AppCompatActivity
,请确保你设置了“Theme.AppCompat
或类似主题的活动主题”(Google Doc)。
注意: android.support.v7.app.AppCompatActivity
是android.support.v4.app.FragmentActivity
类的一个子类(参见AppCompatActivity ref doc)。
在你的菜单文件夹中制作一个.menu的xml文件并添加这个xml
<item android:id="@+id/action_search" android:icon="@android:drawable/ic_menu_search" android:title="@string/action_search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always|collapseActionView" />
在你的片段类中覆盖了这个方法
implement SearchView.OnQueryTextListener in your fragment class @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setHasOptionsMenu(true); }
现在只需在片段类中设置菜单XML文件
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_main, menu); final MenuItem item = menu.findItem(R.id.action_search); final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionCollapse(MenuItem item) { // Do something when collapsed return true; // Return true to collapse action view } @Override public boolean onMenuItemActionExpand(MenuItem item) { // Do something when expanded return true; // Return true to expand action view } }); }
你的代码很好。 只有超级在方法中失踪:
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // TODO add your menu : inflater.inflate(R.menu.my_menu, menu); //TODO call super super.onCreateOptionsMenu(menu, inflater); }
在创build片段视图后设置选项菜单对我来说效果很好。
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setHasOptionsMenu(true); }
如果以上所有都不起作用,则需要debugging并确保onCreateOptionsMenu函数已被调用(通过放置debugging或写入日志…)
如果没有运行,也许你的Android主题不支持操作栏。 打开AndroidManifest.xml并为主题支持操作栏设置android:theme
的值 :
<activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/Theme.AppCompat">
在你的onCreate方法上添加setHasOptionMenu()
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }
然后覆盖你的onCreateOptionsMenu
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.add("Menu item") .setIcon(android.R.drawable.ic_delete) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); }