web-dev-qa-db-fra.com

Android Composant de navigation a un retard lors de la navigation via NavigationDrawer

Je mets à jour mon application vers les composants de l'architecture de navigation et je constate qu'elle présente un décalage remplaçant les fragments qui est visible dans le NavigationDrawer et qui ne se ferme pas correctement.

Jusqu'à présent, je suivais cette approche:

https://vikrammnit.wordpress.com/2016/03/28/facing-navigation-drawer-item-onclick-lag/

Je navigue donc dans onDrawerClosed à la place de onNavigationItemSelected pour éviter le problème.

Cela a été un problème très courant, mais il est de retour. En utilisant le composant de navigation, il est à nouveau décalé et je ne vois pas de moyen de l'implémenter dans onDrawerClosed.

Ce sont des réponses plus anciennes avant le composant de navigation

décalage du tiroir de navigation sur Android

Cliquez sur l'élément de DrawerLayout - Quel est le bon moment pour remplacer le fragment?

Merci beaucoup.

16
Javier Delgado

Je m'attaque à ce problème en écrivant cette réponse. Après quelques tests, j'ai conclu que le code que j'exécute en fragment juste après sa création (comme l'initialisation de l'adaptateur RecyclerView et son remplissage avec des données, ou la configuration de l'interface utilisateur) entraîne un décalage du tiroir car tout se passe simultanément.

Maintenant, la meilleure idée que j'ai eue est similaire à certaines anciennes solutions qui reposent sur onDrawerClosed. Nous retardons l'exécution de notre code en fragments jusqu'à la fermeture du tiroir. La disposition du fragment deviendra visible avant la fermeture du tiroir, il aura donc toujours l'air rapide et réactif.

Notez que j'utilise également le composant de navigation.

Tout d'abord, nous allons créer une interface et l'implémenter en fragments.

interface StartFragmentListener {
    fun configureFragment()
}

Dans la configuration d'activité, DrawerListener comme:

private fun configureDrawerStateListener(){
    psMainNavDrawerLayout.addDrawerListener(object: DrawerLayout.DrawerListener{
        override fun onDrawerStateChanged(newState: Int) {}
        override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
        override fun onDrawerOpened(drawerView: View) {}

        override fun onDrawerClosed(drawerView: View) {
            notifyDrawerClosed()
        }

    })
}

Pour notifier à un fragment que le tiroir a été fermé et qu'il peut effectuer des opérations entraînant un décalage:

private fun notifyDrawerClosed(){
    val currentFragment =
            supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
                    ?.childFragmentManager?.primaryNavigationFragment

    if(currentFragment is StartFragmentListenr && currentFragment != null)
        currentFragment.configureFragment()

}

Si vous ne naviguez pas vers le fragment à partir du tiroir (par exemple en appuyant sur le bouton de retour), vous devez également informer le fragment de faire son travail. Nous implémenterons FragmentLifecycleCallbacksListener:

private fun setupFragmentLifecycleCallbacksListener(){
    supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
            ?.childFragmentManager?.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {

        override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
            super.onFragmentActivityCreated(fm, f, savedInstanceState)

            if (!psMainNavDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                if (f is StartFragmentListener)
                    f.configureFragment()
            }

        }
    }, true)
}

En fragment:

class MyFragment: Fragment(), MyActivity.StartFragmentListener {
    private var shouldConfigureUI = true
    ...

    override fun onDetach() {
        super.onDetach()
        shouldConfigureUI = true
    }

    override fun configureFragment() {
        if(shouldConfigureUI){
            shouldConfigureUI = false
            //do your things here, like configuring UI, getting data from VM etc...
            configureUI()
        }
    }
} 

Une solution similaire pourrait être mise en œuvre avec un modèle de vue partagée.

5
UrosKekovic

Évitez le décalage causé par la modification du fragment/de l'activité onNavigationItemSelected - Android

Le tiroir de navigation est l'option la plus couramment utilisée dans les applications, lorsque nous avons plus de cinq options, nous allons vers le menu de navigation.

J'ai vu dans de nombreuses applications que lorsque nous modifions l'option dans le menu de navigation, nous observons qu'elle traîne, certaines personnes sur StackOverflow ont recommandé d'utiliser Handler comme le code ci-dessous:

private void openDrawerActivity(final Class className) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                ProjectUtils.genericIntent(NewDrawer.this, className, null, false);
            }
        }, 200);
    }

Mais dans le code ci-dessus, ce n'est toujours pas fluide et j'ai pensé pourquoi nous ajoutons un gestionnaire peut-être qu'il y a une autre solution après tant de R&D, ce que j'ai compris que nous devons changer le fragment/l'activité lorsque le tiroir va être fermé . voyons la mise en œuvre.

Pour plus de détails sur la solution, veuillez consulter https://Android.jlelse.eu/avoid-the-lag-caused- while-changing-fragment-activity-onnavigationitemselected-Android-28bcb2528ad8 . C'est vraiment utile et utile.

J'espère que vous y trouverez de meilleures solutions!

0
Kalpesh Rupani