2

J'ai une carte d'images où chaque élément est une image utilisateur, une fois cliqué, il ouvre une nouvelle activité avec l'image utilisateur sélectionnée, donc je marque l'image comme élément partagé et utilise des transitions d'activité.Transition d'activité lorsque les données changent

Une partie des actions que j'effectue sur la deuxième activité affecte tous les utilisateurs, donc l'adaptateur appelle notifyDataSetChanged et réinitialise la position en haut de la liste. Quand cela se produit, cela gâche l'animation de retour, quand je ferme la deuxième activité et retourne à la liste, les données ont été changées pour que l'image soit animée à la mauvaise cellule.

J'ai deux questions:

  1. Que puis-je faire pour remapper l'animation à la cellule de droite? Toutes les cellules ont le même ID partagé ...
  2. Si mon utilisateur n'est plus visible dans la liste, comment puis-je remplacer l'animation de retour par une animation différente?

Répondre

1

Que puis-je faire pour remapper l'animation dans la bonne cellule? Toutes les cellules ont le même identifiant partagé.

Dans la première activité, vous devez avoir une clé qui spécifie l'élément qui lance la deuxième activité. Supposons que vous ayez un Map de userId s et User s, c'est-à-dire Map<Integer, User>.

  1. Lorsque vous lancez la deuxième activité passent cette clé de User sur la carte, disons que c'est 42. (Dans la carte 42 -> John Doe, et vous lancez une deuxième activité pour John Doe).
  2. setExitSharedElementCallback() dans la première activité et remplacer onMapSharedElements().

    override fun onMapSharedElements(names: MutableList<String>?, 
              sharedElements: MutableMap<String, View>?) { 
        // we will implement this in step 6        
    } 
    
  3. Override onActivityReenter() en première activité et de reporter la transition avec supportPostponeEnterTransition(), afin de ne pas montrer la transition jusqu'à ce que nous avons fait des actions (par exemple, nous voulons faire défiler la liste afin de montrer l'article).

  4. Dans onActivityReenter() enregistrer le Bundle que vous avez passé de la deuxième activité via Intent (nous verrons à l'étape 7).
  5. Après le report de la transition dans onActivityReenter(), effectuez certaines modifications de l'interface utilisateur en fonction des informations que vous avez ajoutées à ce lot. En particulier, dans notre cas, ce paquet inclura la clé originale Integer du User qui a lancé la deuxième activité. Vous pouvez trouver la place actuelle du User dans la liste avec cette touche, et faites défiler RecyclerView vers cette nouvelle position. Après avoir rendu cet élément visible, vous pouvez appuyer sur la gâchette et laisser le système commencer la transition par supportStartPostponedEnterTransition().
  6. Dans SharedElementCallback::onMapSharedElements() vérifiez le Bundle météo que vous avez enregistré à l'étape 4 est null ou non. Si ce n'est pas null, cela signifierait que vous avez fait quelque chose dans la seconde activité et que vous voulez que le remappage des éléments partagés se produise.Cela signifie que vous devez faire quelque chose comme ceci:

    override fun onMapSharedElements(names: MutableList<String>?, 
               sharedElements: MutableMap<String, View>?) { 
        // `reenterBundle` is the `Bundle` you have saved in step 3 
        if (null != reenterBundle 
          && reenterBundle!!.containsKey("KEY_FROM_ACTIVITY_2") 
          && null != view) { 
         val key = reenterBundle!!.getInt("KEY_FROM_ACTIVITY_2"); 
         val newSharedElement = ... // find corresponding view with the `key` 
         val newTransitionName = ... // transition name of the view 
    
         // clear previous mapping and add new one 
         names?.clear() 
         names?.add(newTransitionName) 
         sharedElements?.clear() 
         sharedElements?.put(newTransitionName, newSharedElement) 
         reenterBundle = null 
        } else { 
         // The activity is exiting 
        }        
    } 
    
  7. En deuxième activité override finishAfterTransition():

    override fun finishAfterTransition() { 
        val data = Intent() 
        data.putExtra("KEY_FROM_ACTIVITY_2", 42) // `42` is the original position that we passed to this activity via Intent when launching it 
        setResult(RESULT_OK, data) 
        super.finishAfterTransition() 
    } 
    

Dans le cas où mon utilisateur ne soit plus visible sur la liste, comment puis-je remplacer l'animation de retour par une animation différente?

Vous pouvez le rendre visible (par exemple en faisant défiler RecyclerView tellement, que votre vue devient visible), ou vous pouvez simplement supprimer des éléments partagés transition à l'étape 6 en dégageant names et sharedElements et ne pas ajouter quoi que ce soit dans les .

J'espère que vous avez appris le concept comment cela fonctionne bien que cela semble un peu brouillon. Mais comme aide pour vous, je peux partager un peu de code d'une application écrite par moi:

MainActivity - MainPresenter

DetailActivity