Ответ 1
Вот трюк, чтобы получить экземпляр меню:
PopupMenu p = new PopupMenu(getContext(), null);
Menu menu = p.getMenu();
Я хочу раздуть метод внешнего onCreateOptionsMenu
объекта меню
Вот пример того, чего я пытаюсь достичь:
Menu menu = // How to create an instance !?
new MenuInflater(context).inflate(R.menu.my_menu, menu)
Меню - это интерфейс, поэтому мне нужно знать, какой класс его реализует. Я просмотрел Android-код, чтобы понять, как создается объект Menu, но все еще не смог найти то, что я ищу.
Изменить 1
Моя цель - запустить событие onOptionsItemSelected(MenuItem item)
из пользовательского представления, которое будет обрабатываться с помощью действия, поэтому мне нужно иметь объект MenuItem с определенным itemId и названием, чтобы передать его с событием.
Если я смогу успешно создать объект Menu, будет легко получить его дочерние элементы MenuItems.
Изменить 2
Я не, пытаясь отобразить меню вообще, я хочу, чтобы заполнить ListView элементами, определенными в меню XML, которые имеют заголовок, значок и itemId и всякий раз, когда щелкнут ListViewItem. хотите запустить событие onOptionsItemSelected(MenuItem item)
, которое обрабатывается в моей активности.
Я знаю, что могу анализировать XML-меню для извлечения информации о элементах, однако я не смогу запустить onOptionsItemSelected(MenuItem item)
без создания стандартного объекта MenuItem для передачи его в качестве аргумента.
Любая помощь будет оценена. Спасибо!
Вот трюк, чтобы получить экземпляр меню:
PopupMenu p = new PopupMenu(getContext(), null);
Menu menu = p.getMenu();
Я нашел два решения программно создать экземпляр меню и раздуть его:
Используя ActionbarSherlock библиотеку или AppCompat v7 library Menu menu = new MenuBuilder(context);
, или вы можете написать ваш собственный MenuBuilder
класс
Использование стандартного SDK для Android:
//Создание экземпляра путем отражения
Menu menu = newMenuInstance(context);
protected Menu newMenuInstance(Context context) {
try {
Class<?> menuBuilderClass = Class.forName("com.android.internal.view.menu.MenuBuilder");
Constructor<?> constructor = menuBuilderClass.getDeclaredConstructor(Context.class);
return (Menu) constructor.newInstance(context);
} catch (Exception e) {e.printStackTrace();}
return null;
}
Когда у вас есть экземпляр меню, вы можете легко раздуть его из XML-ресурса меню в любом месте в вашей программе
new MenuInflater(context).inflate(menuId, menu);
Я тестировал оба метода, и они работают отлично, я бы рекомендовал использовать второй метод со стандартными классами Menu
и MenuItem
из SDK android SDK , даже если ваша активность расширяет SherlockActivity, потому что это будет все равно получите onOptionsItemSelected(MenuItem item)
, независимо от того, стреляете ли вы с помощью android.view.MenuItem
или com.actionbarsherlock.view.MenuItem
Вам не нужно ничего делать с инфлятором, чтобы добавить свои собственные меню. Просто переопределите onCreateOptionsMenu
и начните добавлять свои собственные элементы в меню. Например:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, 1, Menu.NONE, "First");
menu.add(0, 2, Menu.NONE, "Second");
// repeat this to add additional menus
return true;
}
Второй аргумент в add - это id
. Используйте уникальные идентификаторы для идентификации выбранного пункта меню.
Вы можете вытащить экземпляр MenuBuilder (который реализует интерфейс меню), который хранится в PhoneWindow, который используется в Activity. У меня есть рабочее решение, оно использует Java Reflection.
Я создал один проект "InDroid", чтобы выставить несколько важных скрытых методов, переменные из платформы Android - http://code.google.com/p/indroid/
BR, Prasantap >
Я не уверен, почему это уже не ответ, и я знаю, что это старый вопрос, но для будущих читателей.
Если вы просто сделаете это:
val menu = MenuBuilder(context)
MenuInflater(context).inflate(R.menu.menu_XXXX, menu)
MenuBuilder
в конечном итоге расширяет android.view.Menu
. При осмотре это все, что делает PopupMenu
.
fun Context.inflateMenu(@MenuRes menuRes: Int): Lazy<MenuBuilder> = lazy {
MenuBuilder(this)
.also { MenuInflater(this).inflate(menuRes, it) }
}
fun Fragment.inflateMenu(@MenuRes menuRes: Int): Lazy<MenuBuilder> = lazy {
MenuBuilder(context)
.also { MenuInflater(context).inflate(menuRes, it) }
}
class MyActivity : AppCompatActivity(R.layout.activity_my) {
val menu by inflateMenu(R.menu.menu_my)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
}
}
class MyFragment : Fragment(R.layout.fragment_my) {
val menu by inflateMenu(R.menu.menu_my)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}