Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NavController keep two items selected when back is pressed #2634

Closed
2 tasks
felipelindemberg opened this issue Jul 22, 2020 · 5 comments
Closed
2 tasks

NavController keep two items selected when back is pressed #2634

felipelindemberg opened this issue Jul 22, 2020 · 5 comments
Assignees
Labels

Comments

@felipelindemberg
Copy link

About this issue

  • Using the MaterialDrawer + NavController, when I press the back button or when I select a new fragment using the navigation action, the drawer items aren't updated to mark only the current fragment as selected. In this case, two items are marked as selected.

This issue can be reproduced in the sample:
1 - Open the sample and select Nav Controller Drawer
2 - Click in "Go to fragment 1"
3 - Open the drawer and see two selected items
4 - Close the Drawer and press back button to back to home fragment
5 - Open the drawer and check that the items keep selected

Additional Info

  • In the sample, after clicks in "Go to fragment 1" and "Go to fragment 2", if you click in "Go to fragment 3", the drawer menu is updated and works correctly. The "Go to fragment 3" is in StickyDrawerItems.

Details

  • [ 8.1.3] Used library version
  •  Used support library version
  • [4.0.0 ] Used gradle build tools version
  • [4.0.1 ] Used tooling / Android Studio version
  •  Other used libraries, potential conflicting libraries
    Screenshot_1595437053
@Mcgode
Copy link

Mcgode commented Aug 3, 2020

Can confirm. Having the same issue here.

The issue seems to happen whenever I do a manual nav controller navigate:

findNavController().navigate(R.id.my_navigation_destination_id)

// Or
findNavController.navigateUp()

My back button is overridden to have a custom behavior and uses the navigateUp() function.

If I had to hazard a guess, it looks like the list/set of selected drawer items is only reset when selecting a new item (an item not belonging in the selected item list), and when you do a manual navigation, that reset doesn't happen (though the drawer seems to capture the navigate event correctly)

@felipelindemberg
Copy link
Author

My fast solution was override the setupWithNavController method from DrawerNavigationUI and force the update of itemadapter.itemList to keep only one selected item when onDestinationChanged is called.

@mikepenz mikepenz self-assigned this Aug 3, 2020
@Mcgode
Copy link

Mcgode commented Aug 5, 2020

My fast solution was override the setupWithNavController method from DrawerNavigationUI and force the update of itemadapter.itemList to keep only one selected item when onDestinationChanged is called.

I've been trying to implement your quick fix, I've successfully been able to complement DrawerNavigationUI's onDestinationChanged method with my own code additions, but I'm having issues forcing the update of itemAdapter.itemList / itemAdapter.adapterItems.
Could you develop your answer a bit more? (a code sample would also be much appreciated)

@felipelindemberg
Copy link
Author

I created a function to deselect the items different of the last selected item (based on identifier).

fun unselectItemInDrawer(id: Int) {
                        val items = drawerWeak!!.itemAdapter.itemList.items
                        for (i in 0 until items.size) {
                            val item = items[i]

                            if (item.identifier != id.toLong() && item.isSelected) {
                                drawerWeak.selectExtension.deselectByIdentifier(item.identifier)
                            } else if (item is CustomExpandableDrawer) {
                                drawerWeak.selectExtension.deselectByIdentifier(item.identifier)
                            }
                        }

                    }

And onDestinationChanged I call this function in the last line.

if (drawerWeak?.itemAdapter?.adapterItems?.filterIsInstance<NavigationDrawerItem<*>>()
                            ?.handleSelection() != true
                    ) {
                        // if we did not match the normal items, also check the footer
                        if (drawerWeak?.footerAdapter?.adapterItems?.filterIsInstance<NavigationDrawerItem<*>>()
                                ?.handleSelection() != true
                        ) {
                            // if footer also did not match, go to sticky
                            drawerWeak?.stickyDrawerItems?.filterIsInstance<NavigationDrawerItem<*>>()
                                ?.handleSelection()
                        }
                    }

                    unselectItemInDrawer(destination.id)

This gist has some changes that I made: https://gist.github.com/felipelindemberg/847ba3c3d67f2fabff482ee0910e1fdf

My menu has PrimaryDrawerItem, ExpandableItem and NavigationDrawerItem. I had to update the listener to receive events when the primaryItem is clicked, but this is not related with the issue.

I think that just adding this function to unselect the items will solve this issues. I need to check the behavior for select items that are not top level. Whether to keep any element selected in the menu. Today does not select.

@mikepenz
Copy link
Owner

mikepenz commented Aug 7, 2020

Sorry I did not follow this issue as close as I should have.
I see you came up with different options to resolve the problem.

Hopefully this did not cause major problems yet and the workaround is working?

@mikepenz mikepenz added the bug label Aug 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants