11

I have this Layout:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- The ActionBar -->
    <include
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/flContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

<!-- The navigation drawer -->
<android.support.design.widget.NavigationView
    android:id="@+id/nvView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@android:color/white"
    app:menu="@menu/drawer_menu"
    app:headerLayout="@layout/nav_header"/>

So, looking that in NavigationView we have the attribute:

  app:menu="@menu/drawer_menu"

And I have this XML id menu folder.

I wanna make dynamic menus, ie, in code I should mount the 'MenuItem' objects and set into NavigationView.

Is this correct? Is this best pratice? Is this possible?

Note: My code is working with 'static drawer_menu', I want to improve it.

I'm waiting.

[EDIT]

I make it:

 Menu menu = nvDrawer.getMenu();
        for (KSMenuItem kmi : menus.values()) {
            if (menu.size() == 0) {
                menu.add(kmi.getId());
            }
            if (menu.getItem(kmi.getId()) == null) {
                menu.add(kmi.getId());
            }
            MenuItem mi = menu.getItem(kmi.getId());
            mi.setIcon(kmi.getIcon());
            mi.setTitle(kmi.getTittle());
        }

But this error happened:

06-27 15:26:15.538 15335-15335/? E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.example.sticdev30.newdrawer, PID: 15335 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sticdev30.newdrawer/com.example.sticdev30.newdrawer.MainActivity}: android.content.res.Resources$NotFoundException: String resource ID #0x1

KSMenuItem is a POJO with my menu data. In kmi.id I informed incremental integers...

I'm waitning

alfalfa
  • 87
  • 8
Dimmy Magalhães
  • 357
  • 1
  • 6
  • 21

4 Answers4

35

You can re-inflate NavigationViewat runtime with 2 lines of code using public method inflateMenu. In this example i re-inflate with new_navigation_drawer_items.xml

navigationView.getMenu().clear(); //clear old inflated items.
navigationView.inflateMenu(R.menu.new_navigation_drawer_items); //inflate new items.
Trung Nguyen
  • 7,442
  • 2
  • 45
  • 87
12

You can add menus dynamically by following steps :

Step1. Obtain menu object from Navigation View NavigationView.getMenu()

Step2. Add any item to the menu using Menu.add()

Neeraj Kumar
  • 943
  • 4
  • 16
  • The method [Menu.add(int)](http://developer.android.com/reference/android/view/Menu.html#add(int)) expects a string resource id. From the logs checkout fifth line it says resource(String resource) not found. – Neeraj Kumar Jun 29 '15 at 02:54
3

We can dynamically add/remove menu items. Suppose we have this menu items `

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_home"
        android:icon="@mipmap/home_icon_x48"
        android:title="Home" />
    <item
        android:id="@+id/nav_part_catalouge"
        android:icon="@mipmap/catalogue_icon_x48"
        android:title="Parts Catalogue" />
    <item
        android:id="@+id/nav_favourite"
        android:icon="@mipmap/my_favourate_x48"
        android:title="My-Favourite" />\
    <item
        android:id="@+id/nav_opencarrequest"
        android:icon="@mipmap/cart_request"
        android:title="Cart-Request" />

    <item
        android:id="@+id/nav_setting"
        android:icon="@mipmap/settings_x48"
        android:title="Settings" />
</group>


<item android:title="">
    <menu>
        <item
            android:id="@+id/nav_logout"
            android:icon="@mipmap/logout_icon_x48"
            android:title="Logout" />
    </menu>
</item>

`

In Activity we can add or remove menuitems based on our condition

protected void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);// your activity layout here
   NavigationView navigationView= (NavigationView) findViewById(R.id.nav_view); // navigation view which holds menu items
   navigationView.setNavigationItemSelectedListener(this);
   if(yourCondition){
          navigationView.getMenu().getItem(0).setVisible(false); //if you want to hide first item
          navigationView.getMenu().getItem(1).setVisible(true); // if you want to show second menu item should be visible
  }


}

Hope it will help.

1

Seems like kmi.getId() returns int(or long).

But Menu.add(int) adds menu with title from the given string resources, which is usually represented as R.string.something, and not for usual integer values.

Menu.add(CharSequence) does add menu with title of CharSequence, so you need to do some int-to-string conversion like menu.add(kmi.getId() + "");

WKBae
  • 26
  • 3