RecyclerView共享元素过渡不起作用

问题描述

我的目标:GIF

我遵循this guide在我的应用中实现共享元素转换

我的结果:Screen Capture

问题: 正在共享动画但是ItemmovieFragment中的图像来自容器的左上角

无法找出解决方案。

请提出一些解决方

这是代码

ItemmovieFragment complete code

   class ItemmovieFragment  : Fragment() {

    private lateinit var itemmovieviewmodel: Itemmovieviewmodel
    private lateinit var args : ItemmovieFragmentArgs

    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentItemmovieBinding.inflate(inflater)


      //  (activity as AppCompatActivity).supportActionBar?.hide()

        sharedElementEnterTransition =    TransitionInflater.from(context).inflateTransition(android.R.transition.move)

      
     // rest of the code
    }

    override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)

        ViewCompat.setTransitionName(image_poster,args.itemiId.toString())
        Toast.makeText(context,"id: ${args.itemiId}",Toast.LENGTH_SHORT).show()

    }
}

ItemmovieFragment-布局 complete code

  <androidx.cardview.widget.CardView
            android:id="@+id/poster"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            app:cardCornerRadius="4dp"
            app:cardElevation="10dp"
            app:cardMaxElevation="10dp"
            app:layout_constraintBottom_toTopOf="@+id/scrollView2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/scrollView2">


            <ImageView
                android:id="@+id/image_poster"
                android:layout_width="120dp"
                android:layout_height="170dp"
                android:layout_margin="0dp"
                android:padding="0dp"
                android:scaleType="centerCrop"
                app:imageUrl="@{itemmovieviewmodel.movieInf.posterPath}"
                app:srcCompat="@drawable/stp" />

        </androidx.cardview.widget.CardView>

CompletedFragment complete code

       class CompletedFragment(private var type : String) : Fragment() {
    
    
        //firebase
        private lateinit var firebaseDatabase: FirebaseDatabase
        private lateinit var dbReference: DatabaseReference
        private lateinit var firebaseAdapter: FirebaseRVAdapter
        private lateinit var auth: FirebaseAuth
    
        override fun onCreateView(
            inflater: LayoutInflater,savedInstanceState: Bundle?
        ): View? {
            val binding = FragmentCompletedBinding.inflate(inflater)
    
    
    
    
    // rest of the code...
    
    
    
            firebaseAdapter = FirebaseRVAdapter(FirebaseRVAdapter.ItemClickListener { item ->
    
                val id : Int = item.id!!.toInt()
                val extras = FragmentNavigatorExtras(
                    poster to item.id!!
                )
    
                if(type == TV)
                findNavController().navigate(MyWatchlistFragmentDirections.actionGlobalItemTvFragment(id))
               else
                findNavController().navigate(MyWatchlistFragmentDirections.actionMyWatchlistFragmentToItemmovieFragment(id),extras)  // this is the navigation line for shared animation
    
            },optionss)
    
            binding.myfirebaseList.adapter = firebaseAdapter
    
            return binding.root
        }
//rest of the code
}

FirebaseRVAdapter

 package com.utkarsh.fxn.ui.mywatchlist


class FirebaseRVAdapter(private val clickListener: ItemClickListener,options: FirebaseRecyclerOptions<TvFirebase>)
    : FirebaseRecyclerAdapter<TvFirebase,FirebaseRVAdapter.tvFirebaseViewHolder>(options) {
    class tvFirebaseViewHolder ( private var binding: MywatchlistListItembinding) : RecyclerView.ViewHolder(binding.root) {


        fun bind(
            tvfirebase: TvFirebase,clickListener: ItemClickListener
        ){
            ViewCompat.setTransitionName(binding.poster,tvfirebase.id)  //setting transition name
            binding.tvFirebase=tvfirebase
            binding.clickListener=clickListener
        }

    }

    override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): tvFirebaseViewHolder {
        return tvFirebaseViewHolder(MywatchlistListItembinding.inflate(LayoutInflater.from(parent.context)))
    }

    override fun onBindViewHolder(holder: tvFirebaseViewHolder,position: Int,model: TvFirebase) {
        return holder.bind(model!!,clickListener)
    }

    class ItemClickListener(val listener : (tvfirebase: TvFirebase) -> Unit){

        fun OnClick(tvfirebase: TvFirebase) = listener(tvfirebase)
    }


}

已完成片段项目的图像XML complete file

<ImageView
            android:id="@+id/poster"
            android:layout_width="114dp"
            android:layout_height="170dp"
            android:layout_marginStart="4dp"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            app:imageUrl="@{tvFirebase.poster_path}"
            android:scaleType="centerCrop"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.013"
            tools:srcCompat="@drawable/smol" />

解决方法

项目和详细信息屏幕的名称必须相同。

<ImageView
            android:id="@+id/poster"
            android:layout_width="114dp"
            android:layout_height="170dp"
            android:layout_marginStart="4dp"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:transitionName="image_poster"
            app:imageUrl="@{tvFirebase.poster_path}"
            android:scaleType="centerCrop"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.013"
            tools:srcCompat="@drawable/smol" />