J'essaie de faire une transition avec une simple animation d'un élément partagé entre des fragments. Dans le premier fragment, j'ai des éléments dans RecyclerView, dans le second - exactement le même élément (défini dans une disposition xml séparée, dans la liste les éléments sont également de ce type) en haut et des détails dans le reste de la vue. Je donne différents transitionNames pour tous les éléments dans bindViewHolder et dans onCreateView du fragment cible, je les lis et les attribue à l'élément dont je veux faire la transition. Quoi qu'il en soit, l'animation ne se produit pas et je n'ai pas d'autres idées. Ci-dessous, je mets mes extraits de code des fragments source et cible et de l'adaptateur de liste :
ListAdapter :
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = list[position]
ViewCompat.setTransitionName(holder.view, item.id)
holder.view.setOnClickListener {
listener?.onItemSelected(item, holder.view)
}
...
}
interface interactionListener {
fun onItemSelected(item: ItemData, view: View)
}
ListFragment (Source) :
override fun onItemSelected(item: ItemData, view: View) {
val action = ListFragmentDirections.itemDetailAction(item.id)
val extras = FragmentNavigatorExtras(view to view.transitionName)
val data = Bundle()
data.putString("itemId", item.id)
findNavController().navigate(action.actionId, data, null, extras)
}
SourceFragmentLayout :
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_overview_row" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
DetailFragment (Cible) :
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView = inflater.inflate(R.layout.fragment_detail, container, false)
val itemId = ItemDetailFragmentArgs.fromBundle(arguments).itemId
(rootView.findViewById(R.id.includeDetails) as View).transitionName = itemId
sharedElementEnterTransition = ChangeBounds().apply {
duration = 750
}
sharedElementReturnTransition= ChangeBounds().apply {
duration = 750
}
return rootView
}
DetailFragmentLayout :
<include
android:id="@+id/includeDetails"
layout="@layout/item_overview_row"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
ItemOverviewRowLayout (celui-ci est inclus en tant qu'élément dans le recyclerView et dans le fragment cible en tant qu'en-tête) :
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical" >
J'ai également créé une autre application utilisant la navigation Jetpack, des éléments partagés et des éléments décrits par le même layout.xml et cela fonctionne puisque je ne fais pas de transition entre le recyclerView et le fragment cible. Peut-être que je me trompe en fixant le nom de la transition à la vue trouvée dans le fragment cible ? Je ne sais pas comment faire autrement, car les ID des layouts inclus dans la cible doivent être uniques à cause des éléments du recyclerView.