Как я могу динамически создавать пункты меню?

Я создаю приложение для Android и пытаюсь создать систему управления пользователями, в которой пользователи могут входить в систему, выходить из нее и т. д. Я хочу отображать пункт меню входа в систему, если пользователь вышел из системы, и кнопку выхода, если пользователь вошел в систему в. Как я могу сделать это динамически?

Это файл макета прямо сейчас:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/add" android:title="Add" android:icon="@drawable/ic_menu_add"/>
  <item android:id="@+id/list" android:title="List" android:icon="@drawable/ic_menu_list"/>
  <item android:id="@+id/refresh" android:title="Refresh" android:icon="@drawable/ic_menu_refresh"/>
  <item android:id="@+id/login" android:title="Login" android:icon="@drawable/ic_menu_login"/>
</menu>

Это моя Java прямо сейчас:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.activity_main, menu);
    return(super.onCreateOptionsMenu(menu));
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    System.out.println(item.getItemId()==R.id.add);
    if (item.getItemId()==R.id.add)
    {
        //Cannot add spot unless we have obtained the users current location. 
        if((currentLat != 0) && (currentLng != 0))
        {

            System.out.println("loggedin? : "  + auth.isLoggedIn());
            if(!auth.isLoggedIn())
            {
                Toast.makeText(MainActivity.this, "You must be logged in to add a new spot",
                        Toast.LENGTH_LONG).show();
            }
            else
            {


                Intent addIntent = new Intent(MainActivity.this, AddSpot.class);
                Bundle b = new Bundle();
                b.putDouble("currentLat", currentLat);
                b.putDouble("currentLng", currentLng);
                addIntent.putExtras(b);
                startActivity(addIntent);
                return(true);
            }
        }
    }   
    else if(item.getItemId()==R.id.list)
    {
        //Pointless showing them a blank screen if nothing is retrieved from the server
        if(list != null)
        {
            Intent listIntent = new Intent(MainActivity.this, ListLocations.class);
            listIntent.putExtra("list", list);
            startActivity(listIntent);
            return(true);
        }
    }

    if(item.getItemId()==R.id.refresh)
    {
        finish();
        startActivity(getIntent());
        return(true);       
    }

    if(item.getItemId()==R.id.login)
    {
        Intent loginIntent = new Intent(MainActivity.this, LoginActivity.class);
        startActivity(loginIntent);
        return(true);   
    }

    return(super.onOptionsItemSelected(item));
}

person Johnathan Au    schedule 22.03.2013    source источник


Ответы (6)


Как динамически добавлять пункты меню в активность Android

public class yourActivity extends Activity {
    ...
    private static final int MENU_ADD = Menu.FIRST;
    private static final int MENU_LIST = MENU.FIRST + 1;
    private static final int MENU_REFRESH = MENU.FIRST + 2;
    private static final int MENU_LOGIN = MENU.FIRST + 3;

    /**
     * Use if your menu is static (i.e. unchanging)
     */
    /*
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_ADD, Menu.NONE, R.string.your-add-text).setIcon(R.drawable.your-add-icon);
        menu.add(0, MENU_LIST, Menu.NONE, R.string.your-list-text).setIcon(R.drawable.your-list-icon);
        menu.add(0, MENU_REFRESH, Menu.NONE, R.string.your-refresh-text).setIcon(R.drawable.your-refresh-icon);
        menu.add(0, MENU_LOGIN, Menu.NONE, R.string.your-login-text).setIcon(R.drawable.your-login-icon);
        return true;
    }
    */

    /**
     * Gets called every time the user presses the menu button.
     * Use if your menu is dynamic.
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.clear();
        if(enableAdd)
            menu.add(0, MENU_ADD, Menu.NONE, R.string.your-add-text).setIcon(R.drawable.your-add-icon);
        if(enableList)
            menu.add(0, MENU_LIST, Menu.NONE, R.string.your-list-text).setIcon(R.drawable.your-list-icon);
        if(enableRefresh)
            menu.add(0, MENU_REFRESH, Menu.NONE, R.string.your-refresh-text).setIcon(R.drawable.your-refresh-icon);
        if(enableLogin)
            menu.add(0, MENU_LOGIN, Menu.NONE, R.string.your-login-text).setIcon(R.drawable.your-login-icon);
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);

        switch (item.getItemId()) {
        case MENU_ADD: doAddStuff(); break;
        case MENU_LIST: doListStuff(); break;
        case MENU_REFRESH: doRefreshStuff(); break;
        case MENU_LOGIN: doLoginStuff(); break;
        }
        return false;
    }

В следующем конкретном примере добавляется опция MENU_LOGOUT, если пользователь вошел в систему.

    private static final int MENU_LOGOUT = MENU.FIRST + 4;

    public boolean onPrepareOptionsMenu(Menu menu) {
        ...
        if(auth.isLoggedIn()) {
            menu.add(0, MENU_LOGOUT, Menu.NONE, R.string.your-logout-text).setIcon(R.drawable.your-logout-icon);
        }
        ...
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        ...
        case MENU_LOGOUT:
            if(auth.isLoggedIn()) {
                doLogout();
            } else {
                Toast.makeText(this, "You must have somehow been logged out between the time the menu button was pressed and now.", Toast.DURATION_LONG).show();
            }
            break;
        ...
    }

Вот и все.

person David Manpearl    schedule 22.03.2013
comment
Привет спасибо. Можете ли вы привести пример, который будет отображать выход из системы, если пользователь вошел в систему? Какой метод я бы добавил эту логику? Кроме того, я не понимаю переменные MENU_ADD... и т.д. - person Johnathan Au; 23.03.2013
comment
Сделанный. Смотрите обновленный ответ выше. Значения menuId необходимы, чтобы вы могли знать, какой пункт меню был нажат пользователем при обработке действия меню в onOptionsItemSelected(). - person David Manpearl; 23.03.2013
comment
Хорошо, мило. Еще несколько вопросов. Метод onPrepareOptionsMenu, мне придется воссоздавать каждый другой элемент, или достаточно той логики, которую вы добавили в них? Переменная MENU_LOGOUT, не будет ли это +3, а не +4, потому что она заменит MENU_LOGIN, когда станет видимой? - person Johnathan Au; 23.03.2013
comment
Вы должны воссоздать логику if() для каждого элемента для каждого элемента. В onPrepareOptionsMenu() вы должны поместить логику, чтобы решить, следует ли отображать пункт меню. Полезно также воссоздать ту же логику в onOptionsItemSelected(). Это на тот случай, если что-то изменится в течение потенциально длительного интервала между моментом, когда пользователь впервые нажимает кнопку меню, и моментом, когда он, наконец, нажимает кнопку определенного пункта меню (т. е. сколько времени он оставляет меню отображаемым до выбора пункта). Не забудьте проголосовать (треугольник) и принять (проверить) правильные ответы. - person David Manpearl; 23.03.2013
comment
Значения идентификатора элемента (например, MENU_LOGOUT) не обязательно должны быть последовательными. Их может быть любое количество. Вы можете иметь столько, сколько хотите. Просто не дублируйте никакие значения. Отображайте только те, которые вам нужны в любой момент времени. Таким образом, вполне нормально иметь один из них для каждой возможной метки меню, даже если некоторые из них отображаются очень редко. - person David Manpearl; 23.03.2013
comment
У меня есть сомнения ... допустим, я получаю 5 пунктов меню из бэкэнда на данный момент (получаю его из бэкэнда, потому что в любое время я могу добавить еще один пункт меню), поэтому приложение будет продолжать получать меню из бэкэнда каждый раз для каждого Посмотреть? Любой идеальный способ сделать это? - person Abhinav; 13.02.2018

В моем случае элементы меню находятся в ArrayList, - попробуйте это, надеюсь, это поможет вам :)

public void onClick(View v)
{
    PopupMenu menu = new PopupMenu(DialogCheckBox.this, v);
    for (String s : limits) { // "limits" its an arraylist  
        menu.getMenu().add(s);
    }
    menu.show();
}
person Agilanbu    schedule 07.12.2016
comment
Спасибо, это здорово. именно то, что я ищу - person Prinkal Kumar; 02.12.2017
comment
Не могли бы вы объяснить, как я могу применить прослушиватели кликов к своим элементам? - person Prinkal Kumar; 02.12.2017

вы можете вызвать invalidateOptionsMenu() (примечание: необходимо использовать библиотеку совместимости, такую ​​​​как actionBarSherlock, для доступа, если вам нужно поддерживать низкие версии API), а затем обновлять пункты меню в соответствии со статусом.

там вы можете скрыть элемент действия входа и показать элемент действия выхода из системы.

вы также можете попробовать обновить сам значок, но я никогда не пробовал.

person android developer    schedule 22.03.2013
comment
приятный дополнительный штрих. Необходимо заменить LOGIN значками LOGOUT, как спросил @johnathan-au, потому что это вызовет повторный вызов onPrepareOptionsMenu() - person Someone Somewhere; 18.01.2017

Простой способ создания пунктов меню:

Dynamic_PopUpMenu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PopupMenu menu = new PopupMenu(DialogCheckBox.this, v);
                menu.getMenu().add("AGIL"); // menus items 
                menu.getMenu().add("AGILANBU"); // menus items
                menu.getMenu().add("AGILarasan");
                menu.getMenu().add("Arasan");
                menu.show();
            }
        });

Попробуйте это :)

person Agilanbu    schedule 29.03.2018

это очень просто

Создать меню

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    for (int i = 0; i < list.size(); i++) {
        menu.add(0, i, 0, "Menu Name").setShortcut('5', 'c');
    }

    return true;
}

чтобы получить подробную информацию из щелкнутого меню

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId(); //to get the selected menu id
    String name = item.getTitle(); //to get the selected menu name

    return super.onOptionsItemSelected(item);
}
person Dushyanth Kandiah    schedule 04.11.2018

person    schedule
comment
Если ваши данные поступают из Apis и вы показываете данные во всплывающем окне, тогда этот код вам поможет. Также это используется для динамического всплывающего окна. - person Safal Bhatia; 17.09.2019