#android #android-optionsmenu
#Android #android-optionsmenu
Вопрос:
Существует ли удобный способ отображения одних и тех же параметров меню опций в нескольких действиях?
Пример: В моем приложении я показываю телегид одним из трех способов.
- Семидневное руководство (TabActivity с 7 вкладками)
- Все каналы «Теперь отображаются» (ListActivity)
- Все отображается сегодня по времени начала (Activity — можно легко изменить на ListActivity)
Для меню опций в TabActivity
код довольно прост…
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
menu.clear();
inflater.inflate(R.menu.gv_options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.view:
...
...
}
}
…но на данный момент кажется, что мне нужно скопировать / вставить его в два других действия, которые мне не нравятся. Если я изменю код меню опций для одного, мне нужно будет сделать это и для двух других.
Единственная альтернатива, о которой я могу подумать, — это у меня есть класс ‘helper’ (POJO), к которому я мог бы добавить метод и передать context
в, чтобы разрешить использование getMenuInflator()
метода, и другой метод, в который я мог бы передать результат item.getItemId()
для обработки с помощью switch-case.
Каков обычный способ выполнения нескольких действий с одним и тем же меню опций?
Ответ №1:
Создайте простой отдельный класс с помощью этих двух методов:
public class MyMenuHandler {
private Activity mActivity;
public MyMenuHandler(Activity activity) {
mActivity = activity;
}
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = mActivity.getMenuInflater();
menu.clear();
inflater.inflate(R.menu.gv_options_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.view:
...
}
}
}
В ваших действиях переопределите эти методы обратного вызова и перенаправьте вызов на экземпляр вашего класса MyMenuHandler:
public class MyActivity1 extends TabActivity {
private MyMenuHandler mMenuHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
...
mMenuHandler = new MyMenuHandler(this);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// you may also add here some items which are specific
// for one activity, not for the others
...
return mMenuHandler.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle selection of your specific items here,
// if none of them has been selected call mMenuHandler method
...
return mMenuHandler.onOptionsItemSelected(item);
}
}
Это позволит вам хранить в одном месте код, который отвечает за выбор ваших основных пунктов меню, поэтому вам не нужно будет беспокоиться о копировании-вставке его во все действия, которые должны иметь одно и то же меню.
Ответ №2:
Один из подходов заключается в использовании наследования в ваших действиях. Создайте базовое действие, которое реализует методы меню опций, и тогда каждое дочернее действие получит эту функциональность. Это рекомендуемый подход на сайте разработчика Android:
Совет: Если ваше приложение содержит несколько действий и некоторые из них предоставляют одно и то же меню опций, рассмотрите возможность создания действия, которое не реализует ничего, кроме методов onCreateOptionsMenu() и onOptionsItemSelected(). Затем расширьте этот класс для каждого действия, которое должно использовать одно и то же меню опций. Таким образом, вам придется управлять только одним набором кода для обработки действий меню, и каждый класс-потомок наследует поведение меню.
К сожалению, это не сработает для вас, поскольку вы наследуете не от самого Activity, а от разных его подклассов, но это «обычный» способ сделать это.
Комментарии:
1. Как оказалось, я забыл, что содержимое вкладки действия «Руководство по 7 дням» на самом деле является ListActivity — я изменил действие «все шоу сегодня …» (№ 3 в моем вопросе) на также ListActivity и определил базовый класс, который теперь расширяют все три. Один из тех моментов, когда невозможно увидеть лес за деревьями. Спасибо.
Ответ №3:
Вы можете инкапсулировать свое меню действий в фрагмент. Таким образом, вам нужно только добавить фрагмент в меню onCreate вашей активности.
Вам нужно вызвать setHasOptionsMenu после создания фрагмента. Для добавления фрагмента add используйте тег вместо идентификатора макета.
Комментарии:
1. Привет. у вас есть какой-нибудь хороший пример (учебное пособие или любой другой пример) для этого? фрагмент для меня совершенно новый.
2. начните с этого developer.android.com/guide/topics/fundamentals/fragments.html
3. Обратите внимание, что это применимо, если вы используете API уровня 11 или выше
4. Или пакета совместимости от Google. Поскольку почти каждое приложение, поддерживающее 4.0 и 2.2, самые последние и широко используемые приложения Android будут использовать эту библиотеку, это не должно быть проблемой
5. Не знал об этом, спасибо. На всякий случай, если это кому-то понадобится: пакет поддержки Android