mikepenz / MaterialDrawer

The flexible, easy to use, all in one drawer library for your Android project. Now brand new with material 2 design.
https://mikepenz.dev
Apache License 2.0
11.67k stars 2.05k forks source link

Unable to fully reset the MaterialDrawerSliderView (account header remains) #2776

Closed carlos-mg89 closed 2 years ago

carlos-mg89 commented 2 years ago

About this issue

Hi everyone!

I'm trying to fully reset the MaterialDrawerSliderView by rebuilding it (after certain user events). The view is almost fully rebuilt, except the AccountHeaderView (which I only create if there's an active profile == user logged in).

Basically, this is the whole process.

1. Scenario with active profile

2. Scenario without active profile

This is my code to build the slider:

private fun build() {
        slider.accountHeader = getAccountHeaderView()
        addNavigationDrawerItems()

        slider.onDrawerItemClickListener = { _, drawerItem, _ ->
            processNavigationDrawerOnClick(drawerItem.identifier.toInt())
            false
        }
        getDrawerLayout()?.closeDrawers()
    }

private fun getAccountHeaderView(): AccountHeaderView? {
        return if (user != null) {
            val accountHeaderView = AccountHeaderView(activity)
            val profileDrawable = ContextCompat.getDrawable(activity, R.drawable.profile)
            profileDrawable?.colorFilter = android.graphics.PorterDuffColorFilter(
                ContextCompat.getColor(activity, R.color.menuProfileTextColor),
                PorterDuff.Mode.SRC_IN
            )
            accountHeaderView.addProfiles(
                ProfileDrawerItem().apply {
                    iconDrawable = profileDrawable
                    name = StringHolder(user?.name)
                    description = StringHolder(user?.email)
                }
            )
            accountHeaderView.headerBackground = ImageHolder(R.color.menuProfileBackgroundColor)
            accountHeaderView.onAccountHeaderListener = { _, _, _ -> showAccountSettingsActivity() }

            return accountHeaderView
        } else {
            null
        }
    }

And the code to reset the slider:

private fun reset() {
        slider.accountHeader?.activeProfile?.let {
            slider.accountHeader?.removeProfile(it)
            slider.accountHeader?.clear()
            slider.accountHeader?.updateHeaderAndList()
            slider.accountHeader = null
        }
        slider.removeAllItems()
        slider.resetDrawerContent()
        build()
    }

If you go from scenario 2, and login, then the account header is properly set, with the active profile information.

However, if you are in the scenario 1, and log out, the account header gets the profile removed, but the background remains there.

image

And I'll expect it to be, as it is in the scenario 2:

image

Details

Checklist

Screenshot_20220421_163214

mikepenz commented 2 years ago

I believe that this could possibly be because not all things are reset. E.g. the different held references:

        binding.slider.accountHeader = null
        binding.slider.headerView = null
        headerView.sliderView = null

(based on the sample activity)

A quick draft of a method to do a detach could look like (this would be a full detach, not 100% tested yet):


    fun AccountHeaderView.detachFromSliderView(sliderView: MaterialDrawerSliderView) {
        this.sliderView = null

        // set the top padding to 0 as this would happen when the AccountHeader is created during Drawer build time
        sliderView.recyclerView.updatePadding(top = /* topInset + */ context.resources.getDimensionPixelSize(R.dimen.material_drawer_padding_top_bottom))

        // remove the views again
        sliderView.headerView = null
        sliderView.accountHeader = null

        // rebuild the things
        updateHeaderAndList()
        sliderView.resetDrawerContent()
    }
carlos-mg89 commented 2 years ago

Thanks a lot! That was it :)