Подтвердить что ты не робот

Как создать экземпляр меню программно? то есть надуть меню снаружи onCreateOptionsMenu

Я хочу раздуть метод внешнего 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 для передачи его в качестве аргумента.

Любая помощь будет оценена. Спасибо!

4b9b3361

Ответ 1

Вот трюк, чтобы получить экземпляр меню:

PopupMenu p  = new PopupMenu(getContext(), null);
Menu menu = p.getMenu();

Ответ 2

Я нашел два решения программно создать экземпляр меню и раздуть его:

  • Используя 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

Ответ 3

Вам не нужно ничего делать с инфлятором, чтобы добавить свои собственные меню. Просто переопределите 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. Используйте уникальные идентификаторы для идентификации выбранного пункта меню.

Ответ 4

Вы можете вытащить экземпляр MenuBuilder (который реализует интерфейс меню), который хранится в PhoneWindow, который используется в Activity. У меня есть рабочее решение, оно использует Java Reflection.

Я создал один проект "InDroid", чтобы выставить несколько важных скрытых методов, переменные из платформы Android - http://code.google.com/p/indroid/

BR, Prasanta​​p >

Ответ 5

Я не уверен, почему это уже не ответ, и я знаю, что это старый вопрос, но для будущих читателей.

Если вы просто сделаете это:

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)

        ...
    }
}