Меню опций Android во фрагменте
Я пытаюсь добавить элемент в меню "Параметры" из группы фрагментов.
Я создал новый 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 Кажется, не работает.
19 ответов:
вызов супер метод:
@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); }поместите инструкции журнала в код, чтобы увидеть, если метод не вызывается или если меню не изменяется вашим кодом.
также убедитесь, что вы звоните
SetHasOptionsMenuinonCreateчтобы уведомить фрагмент, что он должен участвовать в обработке меню опций.
у меня была та же проблема, но я думаю, что лучше обобщить и ввести последний шаг, чтобы заставить его работать:
добавьте метод setHasOptionsMenu (true) в свой фрагмент
onCreate(Bundle savedInstanceState)метод.переопределить
onCreateOptionsMenu(Menu menu, MenuInflater inflater)(Если вы хотите сделать что-то другое в меню фрагмента) иonOptionsItemSelected(MenuItem item)методы в вашем фрагменте.внутри
onOptionsItemSelected(MenuItem item)метод действия, убедитесь, что вы возвращаете false, когда пункт меню действие будет реализовано вonOptionsItemSelected(MenuItem item)метод фрагмента.пример:
активность
@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; }
Если вы найдете
onCreateOptionsMenu(Menu menu, MenuInflater inflater)метод не вызывается, убедитесь, что вы звоните следующей из фрагментаonCreate(Bundle savedInstanceState)способ:setHasOptionsMenu(true)
В моем случае, мне нужно меню, чтобы обновить
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; }меню "Файл".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вы должны добавить все пункты меню. Затем вы можете скрыть элементы, которые вы не хотите видеть в исходной загрузки..xml
<item android:id="@+id/action_newItem" android:icon="@drawable/action_newItem" android:showAsAction="never" android:visible="false" android:title="@string/action_newItem"/>добавить
setHasOptionsMenu(true)в методе onCreate () для вызова элементов меню в вашем классе фрагментов.FragmentClass.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }вам не нужно переопределять
onCreateOptionsMenuв вашем классе фрагментов снова. Пункты меню можно изменить (добавить/удалить) путем переопределенияonPrepareOptionsMenuметод доступен в фрагменте.@Override public void onPrepareOptionsMenu(Menu menu) { menu.findItem(R.id.action_newItem).setVisible(true); super.onPrepareOptionsMenu(menu); }
вы должны использовать меню.очистить () перед раздуванием меню.
@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); }
В моем случае, вот шаги.
Шаг 1
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Here notify the fragment that it should participate in options menu handling. setHasOptionsMenu(true); }Шаг 2
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // First clear current all the menu items menu.clear(); // Add the new menu items inflater.inflate(R.menu.post_stuff, menu); super.onCreateOptionsMenu(menu, inflater); }Шаг 3
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.post_stuff: Log.d(TAG, "Will post the photo to server"); return true; case R.id.cancel_post: Log.d(TAG, "Will cancel post the photo"); return true; default: break; } return super.onOptionsItemSelected(item); }
У меня была такая же проблема, мои фрагменты страницы ViewPager. Причина, по которой это происходило, заключается в том, что я использовал child fragment manager, а не диспетчер фрагментов поддержки активности при создании экземпляра FragmentPagerAdapter.
Если вы хотите добавить меню custom
@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; }
ваш код в порядке. Только супер не хватало в методе:
@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); }
Я сходил с ума, потому что ни один из ответов здесь не работал для меня.
чтобы показать меню мне пришлось позвонить:
setSupportActionBar(toolbar)готово!
Примечание: Если ваш
toolbarвид не находится в том же макете активности вы не можете использовать вызов выше непосредственно из вашего класса активности, в этом случае вам нужно будет получить эту активность из вашего класса фрагмента, а затем вызватьsetSupportActionBar(toolbar). Запоминание: ваш класс активности должен расширять AppCompatActivity.надеемся, что этот ответ поможет вам.
TL; DR
использовать
android.support.v7.widget.Toolbarи вобще:toolbar.inflateMenu(R.menu.my_menu) toolbar.setOnMenuItemClickListener { onOptionsItemSelected(it) }Автономная Панель Инструментов
большинство предлагаемых решений, как
setHasOptionsMenu(true)работают только тогда, когда родительская активность имеет панель инструментов в своем макете и объявляет его черезsetSupportActionBar(). Тогда фрагменты могут участвовать в населении меню именно этого ActionBar:фрагмент.onCreateOptionsMenu(): инициализировать содержимое Меню стандартных опций хоста фрагмента.
если вы хотите отдельную панель инструментов и меню для одного конкретного фрагмента вы можете сделать следующее:
menu_custom_fragment.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_save" android:title="SAVE" /> </menu>custom_fragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" /> ...CustomFragment.КТ
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(layout.custom_fragment, container, false) val toolbar = view.findViewById<Toolbar>(R.id.toolbar) toolbar.inflateMenu(R.menu.menu_custom_fragment) toolbar.setOnMenuItemClickListener { onOptionsItemSelected(it) } return view } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_save -> { // TODO: User clicked the save button true } else -> super.onOptionsItemSelected(item) } }Да, это так просто. Вам даже не нужно переопределять
onCreate()илиonCreateOptionsMenu().PS: это работает только с
android.support.v4.app.Fragmentиandroid.support.v7.widget.Toolbar(также обязательно используйтеAppCompatActivityиAppCompatтемы в своемstyles.xml).
настройка меню параметров после создания фрагментного представления хорошо работала для меня.
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setHasOptionsMenu(true); }
моя проблема была немного другая. Я все сделал правильно. Но я наследовал неправильный класс для действия, содержащего фрагмент.
поэтому, чтобы быть ясным, если вы переопределяете
onCreateOptionsMenu(Menu menu, MenuInflater inflater)во фрагменте убедитесь, что ваш класс activity, который содержит этот фрагмент, наследуетandroid.support.v7.app.ActionBarActivity(в случае, если вы хотите поддерживать ниже уровня API 11).я унаследовал
android.support.v4.app.FragmentActivityдля поддержки уровня API ниже 11.
одна вещь, которую я бы добавил к этому, и причина, по которой это не работает для меня.
это похоже на ответ Napster.
убедитесь, что активность хостинга вашего фрагмента расширяется
AppCompatActivity, а неFragmentActivity!public class MainActivity extends AppCompatActivity { }из ссылки Google документация для FragmentActivity:
Примечание: Если вы хотите осуществлять деятельность, которая включает в себя панель действий, вы должны вместо этого использовать класс ActionBarActivity, который является подклассом этого, поэтому позволяет использовать фрагмент API на уровне API 7 и выше.
чтобы обновить ответ Napster --
ActionBarActivityтеперь устарели, используйтеAppCompatActivityвместо.при использовании
AppCompatActivity, также убедитесь, что вы установили "тема деятельностиTheme.AppCompatили аналогичная тема " (Google Doc).Примечание:
android.support.v7.app.AppCompatActivityявляется наследникомandroid.support.v4.app.FragmentActivityкласса (см. AppCompatActivity ref doc).
в папке меню сделать .меню 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 } }); }
Если все вышеперечисленное не работает, вам нужно отладить и убедиться, что функция onCreateOptionsMenu была вызвана (путем размещения debug или write log...)
если он не запущен, возможно, ваша тема Android не поддерживает панель действий. Открываем AndroidManifest.xml и установите значение для
android:themeс темой поддержки панели действий:<activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/Theme.AppCompat">
на onCreate метод add 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); }
Comments