Side Menu menu items with data binding - android

I have a situation here I get a list of booleans based on which I hide and show the side menu items I need to remove boilerplate code and need to bind my side menu menu items based on the data I receive but I don't know how to bind side_menu.xml which is menu with my object.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:icon="#drawable/ic_nav_profile"
android:title="Profile"
android:checkable="false"
/>
<item
android:id="#+id/nav_doctorlist"
android:icon="#drawable/ic_nav_my_doctors"
android:title="My Doctors"
android:checkable="false"/>
<item
android:id="#+id/nav_my_orders"
android:icon="#drawable/ic_nav_my_orders"
android:title="Orders"
android:visible="false"
android:checkable="false"/>
<item
android:id="#+id/nav_searchDoc"
android:icon="#drawable/ic_nav_search_doctors"
android:title="Search Doctors"
android:checkable="false"/>
<item
android:id="#+id/nav_myappointments"
android:icon="#drawable/ic_nav_my_appointments"
android:title="Appointments"
android:checkable="false"
/>
<item
android:id="#+id/nav_instant_doctors"
android:icon="#drawable/ic_nav_instant_doctor"
android:title="Instant Doctor"
android:checkable="false"
android:visible="false"
/>
<item
android:id="#+id/nav_healthrecord"
android:icon="#drawable/ic_nav_my_health_record"
android:title="Medical Records"
android:checkable="false"/>
<item
android:id="#+id/nav_labtests"
android:icon="#drawable/ic_nav_lab_tests"
android:title="Lab Tests"
android:visible="false"
android:checkable="false"/>
<item
android:id="#+id/nav_invoice"
android:icon="#drawable/ic_nav_invoices"
android:title="Invoices"
android:visible="false"
android:checkable="false"/>
<item
android:id="#+id/nav_chat"
android:icon="#drawable/ic_nav_help"
android:title="Help"
android:checkable="false"/>
</group>
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_logout"
android:icon="#drawable/ic_nav_logout"
android:title="Login / Sign Up"
android:checkable="false"/>
</group>
</menu>
Here below is the menu I need to hide and show some items based on my objects data so how do I bind it ? Using data binding.

Related

Add child to a MenuItem within a group in a NavigationView

I already checked some questions but none has a really answer of what I'm looking for.
Basically I'm trying to add an item child to an item parent, or simulate a tree of options in the lateral panel, something like the Google Play app does:
I tried this as a test in my XML file:
<group android:checkableBehavior="single">
<item
android:orderInCategory="0"
android:id="#+id/nav_back"
android:icon="#drawable/ic_arrow_back_black_24dp"
android:title="Regresar a la pagina principal"
/>
</group>
<group android:checkableBehavior="single"
android:id="#+id/groupTypes">
<item
android:orderInCategory="1"
android:id="#+id/nav_negocios"
android:icon="#drawable/ic_local_convenience_store_black_48dp"
android:title="#string/negocios" />
<item
android:orderInCategory="1"
android:id="#+id/nav_hoteles"
android:icon="#drawable/ic_local_hotel_black_48dp"
android:title="#string/hoteles" />
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
<item
android:orderInCategory="1"
android:id="#+id/nav_restaurant"
android:icon="#drawable/ic_restaurant_black_48dp"
android:title="#string/restaurant" />
<item
android:orderInCategory="1"
android:id="#+id/nav_destacado"
android:icon="#drawable/ic_stars_black_48dp"
android:title="#string/destacado" />
</group>
<group android:title="#string/grupo2">
<menu>
<item
android:id="#+id/nav_taxi"
android:orderInCategory="2"
android:icon="#drawable/ic_local_taxi_black_48dp"
android:title="#string/mobility" />
</menu>
</group>
And this is what I got:
The "Bares" item has changed to a category and the item inside is just adding as the original sequence in the group.
Also I tried using the android:menuCategory="container" and android:menuCategory="secondary"options but the result is the same.
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:menuCategory="container"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:menuCategory="secondary"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
Any suggestions?
I couldn't find such an API in source codes. I decompiled Play Store apk file (version 7.7.17.O) with androidtool.
main.xml
<com.google.android.finsky.layout.play.FinskyDrawerLayout>
<com.google.android.finsky.layout.InsetsFrameLayout>
</com.google.android.finsky.layout.InsetsFrameLayout>
<include layout="#layout/play_drawer_container" />
</com.google.android.finsky.layout.play.FinskyDrawerLayout>
play_drawer_container.xml
<LinearLayout>
<ListView android:id="#id/play_drawer_list" style="#style/PlayDrawerList" />
<TextView android:id="#id/play_drawer_docked_action" android:visibility="gone" style="#style/PlayDrawerDockedAction" />
</LinearLayout>
As you can see, menu items are not set via app:menu. It's just a ListView.
You can also see the difference of view bounds when "Show layout bounds" is turned on:
If they have used the default menu items, you should have seen the boundaries matching.
So, answering to your question: it can be implemented with custom approach, menus have no such functionality.
Update
There are a number of ways to implement that kind of functionality:
Using RecyclerView
Using ListView
Using ScrollView
If there are few items in the list, which won't need recycling functionality, than you can stick with ScrollView. Otherwise, prefer either RecyclerView or ListView, where each of item has its own row item xml.
You need to surround your item with the menu, and then add the submenu below it. It might look like this:
<group android:checkableBehavior="single">
<item
android:orderInCategory="0"
android:id="#+id/nav_back"
android:icon="#drawable/ic_arrow_back_black_24dp"
android:title="Regresar a la pagina principal"
/>
</group>
<group android:checkableBehavior="single"
android:id="#+id/groupTypes">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_negocios"
android:icon="#drawable/ic_local_convenience_store_black_48dp"
android:title="#string/negocios" />
<item
android:orderInCategory="1"
android:id="#+id/nav_hoteles"
android:icon="#drawable/ic_local_hotel_black_48dp"
android:title="#string/hoteles" />
<item
android:orderInCategory="1"
android:id="#+id/nav_bares"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/bares">
<menu>
<item
android:orderInCategory="1"
android:id="#+id/nav_barType1"
android:icon="#drawable/ic_local_bar_black_48dp"
android:title="#string/restaurant" />
</menu>
</item>
<item
android:orderInCategory="1"
android:id="#+id/nav_restaurant"
android:icon="#drawable/ic_restaurant_black_48dp"
android:title="#string/restaurant" />
<item
android:orderInCategory="1"
android:id="#+id/nav_destacado"
android:icon="#drawable/ic_stars_black_48dp"
android:title="#string/destacado" />
</menu>
</group>
<group android:title="#string/grupo2">
<menu>
<item
android:id="#+id/nav_taxi"
android:orderInCategory="2"
android:icon="#drawable/ic_local_taxi_black_48dp"
android:title="#string/mobility" />
</menu>
</group>
You can try with drop down menu or expandable list or simple lists which can be seen on click of menu options accordingly in navigation drawer instead of group.
For your first approach, you can make a little edit. That SubItem is also an item an instead of putting everything in group you should put in an item. Try this example below:
<item
android:id="#+id/nav_category_electronics"
android:icon="#drawable/ic_email_black_24dp"
android:title="Electronics">
<menu>
<item
android:id="#+id/nav_subcategory_laptops"
android:icon="#drawable/laptop"
android:title="Laptops" />
<item
android:id="#+id/nav_subcategory_tablet"
android:icon="#drawable/tablet3"
android:title="Tablets" />
<item
android:id="#+id/nav_category_phones"
android:icon="#drawable/smartphone"
android:title="Mobile Phones" />
<item
android:id="#+id/nav_subcategory_gadgets"
android:icon="#drawable/ic_developer_mode_black_18dp"
android:title="Gadgets" />
</menu>
</item>

How to add subitems to navigation drawer in android like expandable list

I'm working on a demo of DrawerLayout with fragments in android,I've implemented it but I want to add subitems to items when it is clicked it should populate the subitems just like an expandable listView. I have found some thread with expandable ListView,But I don't want it,Please suggest me how can I do it?
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Customer">
<menu
>
<item
android:id="#+id/nav_cust_mgmt"
android:icon="#drawable/ic_group"
android:title="Customer Management" >
</item>
<item
android:id="#+id/nav_cust_opn"
android:icon="#drawable/ic_user"
android:title="Customer Operation" />
<item
android:id="#+id/nav_cust_tkt"
android:icon="#drawable/ic_page"
android:title="Customer Tickets" />
</menu>
</item>
<item android:title="LCO">
<menu>
<item
android:id="#+id/nav_dashboard"
android:icon="#drawable/ic_home"
android:title="Dashboard" />
<item
android:id="#+id/nav_stm"
android:icon="#drawable/ic_stmnt"
android:title="Statement of Account" />
<item
android:id="#+id/nav_staf_mgmnt"
android:icon="#drawable/ic_grup"
android:title="Staff Management" />
<item
android:id="#+id/nav_my_tkts"
android:icon="#drawable/ic_page"
android:title="My Tickets" />
<item
android:id="#+id/nav_logout"
android:icon="#drawable/ic_logout"
android:title="Logout" />
</menu>
</item>
</menu>
I want to add subcategories to this.Please help me.
You can create groups in menu file like this
<item
android:id="#+id/nav_menuItem9"
android:title="#string/str_drawer_group1">
<menu android:checkableBehavior="all">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_cust_mgmt"
android:icon="#drawable/ic_group"
android:title="Customer Management" >
</item>
...
</group>
</menu>
</item>
OR you can put expandable list view in drawer part and then handle everything manually. for more about this check this link

Remove subsection and from navigation drawer submenu

I want to remove the unwanted space created in submenu.
Is there any possibility I can achieve it from menu.xml class?
Here is my navigation_drawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/all"
android:checked="true"
android:icon="#drawable/ic_channels"
android:title="All Channels" />
.......
<item
android:id="#+id/other"
android:icon="#drawable/ic_other"
android:title="Others" />
</group>
<item android:title="">
<menu>
<item
android:id="#+id/setting"
android:icon="#drawable/ic_action_settings"
android:title="Settings" />
<item
android:id="#+id/about"
android:icon="#drawable/ic_about"
android:title="About" />
<item
android:id="#+id/share"
android:icon="#drawable/ic_share"
android:title="Share" />
</menu>
</item>
Thanks.
This is how I implement it. Because you are adding a title to a menu it is not recognizing it is empty.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav1"
android:checked="true"
android:title="Pos 1" />
<item
android:id="#+id/nav2"
android:title="Pos 2" />
</group>
<group
android:id="#+id/menu_two"
android:checkableBehavior="single">
<item
android:id="#+id/pos3"
android:title="Pos 3" />
<item
android:id="#+id/pos4"
android:title="Pos 4" />
</group>
</menu>
First, please read this Ian Lake's (Android Developer Advocate) answer:
NavigationView seeks to match the material design specs for the
navigation drawer which state an 8dp space between content areas.
Generally there are no ways to override NavigationView to
specifically break the specifications.
From: How I can remove the unnecessary top padding of the Navigation view?
As you see this undesired padding is sub header of your section.
To delete it, you would need to delete this
<item android:title=""> and </item>
To do it you need ****merge** all menu elements** () into single group (no subsections).
After changes your code should look like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/all"
android:checked="true"
android:icon="#drawable/ic_channels"
android:title="All Channels" />
.......
<item
android:id="#+id/other"
android:icon="#drawable/ic_other"
android:title="Others" />
<menu>
<item
android:id="#+id/setting"
android:icon="#drawable/ic_action_settings"
android:title="Settings" />
<item
android:id="#+id/about"
android:icon="#drawable/ic_about"
android:title="About" />
<item
android:id="#+id/share"
android:icon="#drawable/ic_share"
android:title="Share" />
<menu>
</group>
Still you can do this: How to create a custom navigation drawer in android
If you have a question, please free to ask
Hope it help
To accomplish this programatically, use the overload:
menu.add(int groupId, int itemId, int order, int titleRes)
(and make sure to provide different groupId's for the different sections)

Navigation-drawer group header - how to set up?

I have a menu with groups like below. Is that possible to set a headers for each group? I know that's possible for submenus, but what about first level groups?
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single" android:id="#+id/main_group">
<item
android:id="#+id/leagues_in_progress_item"
android:icon="#drawable/ic_format_line_spacing_black_48dp"
android:title="#string/title_activity_leagues_in_progress" />
<item
android:id="#+id/last_matches_item"
android:icon="#drawable/ic_access_alarm_black_48dp"
android:title="#string/title_activity_last_matches" />
</group>
<group android:checkableBehavior="single" android:id="#+id/another_group">
<item
android:id="#+id/archive_item1"
android:icon="#drawable/ic_folder_open_black_48dp"
android:title="#string/title_activity_archive" />
<item
android:id="#+id/put_score_item3"
android:icon="#drawable/ic_add_circle_outline_black_48dp"
android:title="#string/title_activity_put_score" />
</group>
</menu>
Yes, each group would be an item in your top-level tree. Then just set the title attribute for each of these. Using your code it would be like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="First group"
android:id="#+id/first_group">
<menu android:checkableBehavior="single" android:id="#+id/main_group">
<item
android:id="#+id/leagues_in_progress_item"
android:icon="#drawable/ic_format_line_spacing_black_48dp"
android:title="#string/title_activity_leagues_in_progress" />
<item
android:id="#+id/last_matches_item"
android:icon="#drawable/ic_access_alarm_black_48dp"
android:title="#string/title_activity_last_matches" />
</menu>
</item>
<item
android:title="Second group"
android:id="#+id/second_group">
<menu android:checkableBehavior="single" android:id="#+id/another_group">
<item
android:id="#+id/archive_item1"
android:icon="#drawable/ic_folder_open_black_48dp"
android:title="#string/title_activity_archive" />
<item
android:id="#+id/put_score_item3"
android:icon="#drawable/ic_add_circle_outline_black_48dp"
android:title="#string/title_activity_put_score" />
</menu>
</item>
</menu>

Optional menu item after a submenu not displayed

I have a strange problem on an ActionBar I am setting up on a ListActivity.
Here is the XML I use to setup my menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_search"
android:title="#string/search_filter"
android:icon="#drawable/ic_search"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_start_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_end_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_filters"
android:title="#string/filters"
android:icon="#drawable/ic_filter"
android:showAsAction="always|withText">
<menu>
<item
android:id="#+id/menu_ratings"
android:title="#string/ratings"
android:icon="#drawable/ic_star"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_emotions"
android:title="#string/emotions"
android:icon="#drawable/ic_smi2"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_categories"
android:title="#string/categories"
android:icon="#drawable/ic_folder"
android:showAsAction="always|withText" />
</menu>
<item
android:id="#+id/menu_search_order"
android:title="#string/search_order"
android:icon="#drawable/ic_search_order"
android:showAsAction="ifRoom|withText" />
</item>
</menu>
The menu items menu_search, menu_start_date, menu_end_date and the sub-menu menu_filters are working well but impossible to get the menu menu_search_order from the physical menu button (nothing happens when I press the button).
So I did a little test to see if the problem is not coming from the submenu, I changed the code and commented the submenu part:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_search"
android:title="#string/search_filter"
android:icon="#drawable/ic_search"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_start_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_end_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_filters"
android:title="#string/filters"
android:icon="#drawable/ic_filter"
android:showAsAction="always|withText">
<!-- <menu>
<item
android:id="#+id/menu_ratings"
android:title="#string/ratings"
android:icon="#drawable/ic_star"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_emotions"
android:title="#string/emotions"
android:icon="#drawable/ic_smi2"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_categories"
android:title="#string/categories"
android:icon="#drawable/ic_folder"
android:showAsAction="always|withText" />
</menu> -->
<item
android:id="#+id/menu_search_order"
android:title="#string/search_order"
android:icon="#drawable/ic_search_order"
android:showAsAction="ifRoom|withText" />
</item>
</menu>
After this change, the menu works well and the option is displayed when I push the physical menu button.
So my question is: why is the submenu blocking my last menu to appear in the first case?
Thank you!
I still don't know why the code in my question is not working but I found the trick to finally make it work.
I just moved my optional menu (initially at the bottom) before the submenu in the XML file:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_search"
android:title="#string/search_filter"
android:icon="#drawable/ic_search"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_start_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_end_date"
android:title="#string/date_filter"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_search_order"
android:title="#string/search_order"
android:icon="#drawable/ic_search_order"
android:showAsAction="ifRoom|withText" />
<item
android:id="#+id/menu_filters"
android:title="#string/filters"
android:icon="#drawable/ic_filter"
android:showAsAction="always|withText">
<menu>
<item
android:id="#+id/menu_ratings"
android:title="#string/ratings"
android:icon="#drawable/ic_star"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_emotions"
android:title="#string/emotions"
android:icon="#drawable/ic_smi2"
android:showAsAction="always|withText" />
<item
android:id="#+id/menu_categories"
android:title="#string/categories"
android:icon="#drawable/ic_folder"
android:showAsAction="always|withText" />
</menu>
</item>
</menu>
The order here is not important because this menu is the only one I need to see through the physical menu button.
So after so many tries I found a way how to make those items display everywhere correctly. So the trick is to put all items to group element with some id and also android:checkableBehavior="single" , this is only way I was able to get it to render as defined in xml. If I remove id from first group last two items get merged to previous menu sub items. Quite buggy android menu implementation. It should be reported somewhere, but hopefully someone else will do it.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="#+id/signup_1_identification_group"
android:checkableBehavior="single">
<item
android:id="#+id/dopkkpokadad"
android:title="#string/signup_1_identification" />
</group>
<item
android:id="#+id/kokopj"
android:title="#string/signup_6_nationality">
<menu android:id="#+id/signup_6_nationality_menu">
<group
android:id="#+id/signup_6_nationality_group"
android:checkableBehavior="single">
<item
android:id="#+id/dadceqpovjopeqad"
android:title="Hlavna" />
<item
android:id="#+id/cionno"
android:title="Dalsia" />
<item
android:id="#+id/dkbvyukbadad"
android:title="Materinsky Jazyk" />
</group>
</menu>
</item>
<group
android:id="#+id/signup_last_group"
android:checkableBehavior="single">
<item
android:id="#+id/dafeqpokopqdad"
android:title="#string/signup_7_religion" />
<item
android:id="#+id/dakopefhpoiueqdad"
android:title="#string/signup_8_finalization" />
</group>
</menu>
This is how it is rendered correctly from this xml:
When I remove id from fist group I get back wrong behaviour, last two items gets merged, in some cases they will disappear or other weird stuff happens depending on other layout changes, I believe android menu implementation is just buggy...

Categories

Resources