Меню Android Options в фрагменте
Я пытаюсь добавить элемент в меню опций из группы фрагментов.
Я создал новый класс 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
не запускается.
Ответы
Ответ 1
Вызовите супер метод:
@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);
}
Поместите операторы журнала в код, чтобы увидеть, не вызывается ли метод или не изменяется ли меню вашим кодом.
Также убедитесь, что вы вызываете setHasOptionsMenu(boolean)
в onCreate(Bundle)
чтобы уведомить фрагмент о том, что он должен участвовать в обработке меню параметров.
Ответ 2
У меня была такая же проблема, но я думаю, что лучше подвести итог и ввести последний шаг, чтобы заставить ее работать:
-
Добавьте метод setHasOptionsMenu (true) в метод Fragment onCreate(Bundle savedInstanceState)
.
-
Переопределить onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(если вы хотите сделать что-то другое в своем меню фрагментов) и onOptionsItemSelected(MenuItem item)
в вашем фрагменте.
-
Внутри метода onOptionsItemSelected(MenuItem item)
Activity убедитесь, что вы возвращаете 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 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;
}
Ответ 3
Если вы обнаружите, что метод onCreateOptionsMenu(Menu menu, MenuInflater inflater)
не вызывается, убедитесь, что вы вызываете следующее из метода Fragment onCreate(Bundle savedInstanceState)
:
setHasOptionsMenu(true)
Ответ 4
Если вам нужно menu
для обновления webview
внутри определенного Fragment
, вы можете использовать:
Фрагмент:
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>
Ответ 5
В 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"/>
Добавьте setHasOptionsMenu(true)
в метод onCreate() для вызова пунктов меню в вашем классе Fragment.
FragmentClass.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Вам не нужно переопределять onCreateOptionsMenu
в вашем классе Fragment снова. Пункты меню можно изменить (добавить/удалить), переопределив метод onPrepareOptionsMenu
доступный во фрагменте.
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
Ответ 6
Перед раздуванием меню вам нужно использовать 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);
}
Ответ 7
TL; DR
Используйте android.support.v7.widget.Toolbar
и просто сделайте:
toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
Автономная панель инструментов
Большинство предлагаемых решений, таких как setHasOptionsMenu(true)
работают только тогда, когда родительская активность имеет панель инструментов в макете и объявляет ее через setSupportActionBar()
. Затем Фрагменты могут участвовать в заполнении меню этого точного ActionBar:
Fragment.onCreateOptionsMenu(): инициализировать содержимое стандартного меню параметров узла Fragment.
Если вам нужна отдельная панель инструментов и меню для одного конкретного фрагмента, вы можете сделать следующее:
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.kt
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
).
Ответ 8
В моем случае вот шаги.
Шаг 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);
}
Ответ 9
У меня была такая же проблема, мои фрагменты были страницами ViewPager. Причина, по которой это происходит, заключается в том, что при создании экземпляра FragmentPagerAdapter я использовал диспетчер дочерних фрагментов, а не менеджер фрагментов поддержки операций.
Ответ 10
Если вы хотите добавить свое меню на заказ
@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);
}
Ответ 11
Файл меню:
<?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;
}
Ответ 12
Ваш код в порядке. В методе отсутствовал только супер:
@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);
}
Ответ 13
Я сходил с ума, потому что ни один из ответов здесь не работал для меня.
Чтобы показать меню мне нужно было вызвать: setSupportActionBar(toolbar)
Готово!
Примечание: если ваше представление toolbar
не в том же макете активности, вы не можете использовать вышеуказанный вызов непосредственно из вашего класса активности, в этом случае вам нужно получить это действие из вашего класса фрагмента, а затем вызвать setSupportActionBar(toolbar)
Помните: ваш класс активности должен расширять AppCompatActivity.
Надеюсь, что этот ответ поможет вам.
Ответ 14
Настройка меню параметров после создания представления фрагмента работала хорошо для меня.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
Ответ 15
Моя проблема была несколько иной. Я все сделал правильно. Но я наследовал неправильный класс для работы с фрагментом.
Поэтому, чтобы быть ясным, если вы переопределяете onCreateOptionsMenu(Menu menu, MenuInflater inflater)
в фрагменте, убедитесь, что ваш класс активности, который размещает этот фрагмент, наследует android.support.v7.app.ActionBarActivity
(в случае, если вы хотите поддерживать ниже уровня API 11).
Я наследовал android.support.v4.app.FragmentActivity
, чтобы поддерживать уровень API ниже 11.
Ответ 16
Одна вещь, которую я бы добавил к этому, и причина, по которой она не работала для меня.
Это похоже на ответ Napster.
-
Убедитесь, что активность хоста фрагмента расширяет AppCompatActivity
, а не FragmentActivity
!
public class MainActivity extends AppCompatActivity {
}
Из справочной системы Google Документация для FragmentActivity:
Примечание. Если вы хотите реализовать действие, включающее панель действий, вместо этого вы должны использовать класс ActionBarActivity, который является подклассом этого, поэтому вы можете использовать API-интерфейсы Fragment на уровне API 7 и выше.
-
Чтобы обновить ответ Napster - ActionBarActivity
, теперь устаревший, используйте AppCompatActivity
.
-
При использовании AppCompatActivity
также убедитесь, что вы задали тему активности Theme.AppCompat
или аналогичную тему (Google Doc).
Примечание: android.support.v7.app.AppCompatActivity
является подклассом класса android.support.v4.app.FragmentActivity
(см. AppCompatActivity ref doc).
Ответ 17
В папке вашего меню создайте XML файл .menu и добавьте этот 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
}
});
}
Ответ 18
Если все вышеописанное не работает, вам нужно отладить и убедиться, что функция onCreateOptionsMenu была вызвана (путем размещения отладки или записи журнала...)
Если он не запускается, возможно, ваша тема для Android не поддерживает панель действий.
Откройте AndroidManifest.xml и установите значение для android:theme
с помощью панели действий поддержки темы.
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat">
Ответ 19
в вашем методе 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);
}