(Устаревший) фрагмент onOptionsItemSelected не вызывается
EDIT: Этот вопрос был для устаревшей панели действий Шерлока. Вместо этого теперь должна использоваться библиотека поддержки Android
я добавил опцию меню панели действий под названием share for my fragment
который появляется, но событие выбора не ловится
я добавляю его вот так
@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
MenuItem item = menu.add(0, 7,0, R.string.share);
item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
пытается захватить его в обоих fragment
и fragment activity
как
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 7:
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!");
startActivity(Intent.createChooser(share, "Share Text"));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
и setHasOptionsMenu(true);
на onCreate()
.
8 ответов:
те же проблемы произошли со мной:
onMenuItemSelected события не вызвали в Фрагмент
поиск google не может найти решение, и добавить onMenuItemSelected метод в FragmentActivity не решает его.
наконец решить эту проблему, перейдя по ссылке http://developer.android.com/guide/topics/ui/actionbar.html
Примечание: Если вы добавили пункт меню из фрагмента, через фрагмент класс onCreateOptionsMenu обратного вызова, то система вызывает соответствующий onOptionsItemSelected () метод для этого фрагмента, когда пользователь выбирает один из элементов фрагмента. Однако activity получает возможность сначала обработать событие, поэтому система вызывает onOptionsItemSelected() на activity перед вызовом того же обратного вызова для фрагмента.
это означает, что только если у вас нет этого обработчика элементов меню в onOptionsItemSelected() на activity, то onOptionsItemSelected () на фрагменте будет вызван.
код следующим образом ----- Удалите обработчик для R. действие.добавить on FragmentActivity):
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: popBackStack(); return true; case R.id.action_search: searchAction(); return true; case R.id.action_logout: userLogout(); return true; //case R.id.action_add: //return true; default: return super.onOptionsItemSelected(item); } }
и обработчик для R. действие.добавить на фрагменте выглядит так:
@Override public boolean onOptionsItemSelected(MenuItem item) { Log.d("onOptionsItemSelected","yes"); switch (item.getItemId()) { case R.id.action_add: add(); return true; default: return super.onOptionsItemSelected(item); } }
наконец, не забудьте добавить
setHasOptionsMenu(true);
в вашем методе onCreate в Фрагмент
у меня была та же проблема, но я думаю, что лучше обобщить и ввести последний шаг, чтобы заставить его работать:
добавить
setHasOptionsMenu(true)
метод в вашем фрагментеonCreate(Bundle savedInstanceState)
метод.переопределить
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(если вы хотите сделать что-то другое в меню вашего фрагмента) и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; }
Я заметил, что люди дали вам решение реализовать код для вашего элемента меню в действии, а не фрагмент. Я думаю, что это будет выглядеть гораздо более организованным, если бы вы реализовали код во фрагменте, а не в activity, потому что, на мой взгляд, это выглядит лучше. Для этого выполните следующие действия:
активность
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.SomeIDInTheMenueOfTheActivity: { //something(); break; } default: //do something default and add the code under : return super.onOptionsItemSelected(item); } return true; }
фрагмент
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.SomeIDInFragmentMenue: { break; } default: return super.onOptionsItemSelected(item); } return true; }
теперь строки (и любит): "вернуться супер.onOptionsItemSelected (item);" в действии и фрагменте очень важны, потому что, как если бы вы следовали коду в debug, вы увидите, что функции событий menue будут вызваны сначала в действии, и если элемент не соответствует идентификатору в случае переключения действия, строка degault : "super.onOptionsItemSelected(item);" вызовет функцию onOptionsItemSelected на фрагменте, как мы хотели. (если у вас много фрагментов, убедитесь, что в них есть эта строка, а также вызов иерархия может быть несколько сложнее).
Я использую actionbarsherlock. Это сработало для меня:
1) Создать dummy_menu.меню xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="fill_parent" > <item android:title="" android:showAsAction="never" android:id="@+id/dummyMenu" />
2) в действии раздуть меню следующим образом:
@Override public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.dummy_menu,menu); return super.onCreateOptionsMenu(menu); }
3) во фрагментах onCreateView вызов setHasOptionsMenu (true) и переопределение onCreateOptionsMenu и onOptionsItemSelected также скрыть dummyMenu, как это (во фрагменте)
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.fragment_actions, menu); MenuItem item = menu.findItem(R.id.dummyMenu); item.setVisible(false); super.onCreateOptionsMenu(menu, inflater); }
надеюсь, что это поможет кому-то.
редактировать для actionbar Шерлок использовать
Я должен использовать
public boolean onMenuItemSelected(int featureId, MenuItem item) {
в основной деятельности, чтобы захватить пункт меню
это так просто, что вы можете сделать это в своем фрагменте, чтобы убедиться, что ваше действие будет слушать правильно:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }
У меня была эта проблема. Это было потому, что я переигрывал неправильный метод
onOptionsItemSelected(com.actionbarsherlock.вид.Элемент меню) то, что я использовал.
убедитесь, что вы используете правильный!
вы не привязаны к суперклассу в методах активности. Пожалуйста, имейте onCreateOptionsMenu () возврат супер.onCreateOptionsMenu (меню), и имеют onOptionsItemSelected () возврат супер.onOptionsItemSelected(item) (за исключением элемента, который вы обрабатываете, который должен возвращать true, чтобы указать, что вы обработали событие)