如何解决共享的元素不会返回到RecyclerView项目
我有一个名为MainFragment
的片段,其中包含一个ViewPager,该ViewPager包含另一个名为LibraryFragment
的片段。
LibraryFragment
包含一个RecyclerView以及一个包含ImageView的项目列表。 ImageView的内容随Coil一起加载。
单击某个项目时,LibraryFragment
导航到另一个名为ArtistDetailFragment
的片段,并使用该项目中的ImageView。
问题在于,尽管回车过渡效果很好,但是ImageView
在向后导航时不会返回到列表项,只会消失。香港专业教育学院附上以下示例:
我已经尝试过使用postponeEnterTransition()
和startPostponedEnterTransition()
以及添加SharedElementCallback
的方法,但都效果不佳。我还排除了线圈问题。
这里LibraryFragment
:
class LibraryFragment : Fragment() {
private val musicModel: Musicviewmodel by activityviewmodels()
private val libraryModel: Libraryviewmodel by activityviewmodels()
private lateinit var binding: FragmentLibraryBinding
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View? {
binding = FragmentLibraryBinding.inflate(inflater)
binding.libraryRecycler.adapter = ArtistAdapter(
musicModel.artists.value!!,BindingClickListener { artist,itembinding ->
navToArtist(artist,itembinding)
}
)
return binding.root
}
private fun navToArtist(artist: Artist,itembinding: ItemArtistBinding) {
// When navigation,pass the artistimage of the item as a shared element to create
// the image popup.
findNavController().navigate(
MainFragmentDirections.actionShowArtist(artist.id),FragmentNavigatorExtras(
itembinding.artistimage to itembinding.artistimage.transitionName
)
)
}
}
这里ArtistDetailFragment
:
class ArtistDetailFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,savedInstanceState: Bundle?
): View? {
val binding = FragmentArtistDetailBinding.inflate(inflater)
sharedElementEnterTransition = TransitionInflater.from(requireContext())
.inflateTransition(android.R.transition.move)
val musicModel: Musicviewmodel by activityviewmodels()
val artistId = ArtistDetailFragmentArgs.fromBundle(requireArguments()).artistId
// Get the transition name used by the recyclerview ite
binding.artistimage.transitionName = artistId.toString()
binding.artist = musicModel.artists.value?.find { it.id == artistId }
return binding.root
}
}
还有RecyclerView
适配器/ ViewHolder:
class ArtistAdapter(
private val data: List<Artist>,private val listener: BindingClickListener<Artist,ItemArtistBinding>
) : RecyclerView.Adapter<ArtistAdapter.ViewHolder>() {
override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewHolder {
return ViewHolder(
ItemArtistBinding.inflate(LayoutInflater.from(parent.context))
)
}
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
holder.bind(data[position])
}
// Generic ViewHolder for an artist
inner class ViewHolder(
private val binding: ItemArtistBinding
) : RecyclerView.ViewHolder(binding.root) {
// Bind the view w/new data
fun bind(artist: Artist) {
binding.artist = artist
binding.root.setonClickListener { listener.onClick(artist,binding) }
// Update the transition name with the new artist's ID.
binding.artistimage.transitionName = artist.id.toString()
binding.executePendingBindings()
}
}
}
编辑:我这样使用postponeEnterTransition
和startPostponedEnterTransition
:
// LibraryFragment
override fun onResume() {
super.onResume()
postponeEnterTransition()
// Refresh the parent adapter to make the image reappear
binding.libraryRecycler.adapter = artistAdapter
// Do the Pre-Draw listener
binding.libraryRecycler.viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
这只会使RecyclerView本身刷新,但是,共享元素仍然消失而不是返回到RecyclerView项目。
解决方法
克里斯贝恩斯说;
您可能想知道为什么我们在父级而不是视图本身上设置 OnPreDrawListener。那是因为您的视图可能实际上没有被绘制,因此侦听器永远不会触发并且事务将永远推迟在那里。为了解决这个问题,我们在父级上设置了侦听器,它(可能)会被绘制。
https://chris.banes.dev/fragmented-transitions/
试试这个;
改变
// LibraryFragment
override fun onResume() {
super.onResume()
postponeEnterTransition()
// Refresh the parent adapter to make the image reappear
binding.libraryRecycler.adapter = artistAdapter
// Do the Pre-Draw listener
binding.libraryRecycler.viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
enter code here
到
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View? {
postponeEnterTransition()
binding = FragmentLibraryBinding.inflate(inflater)
binding.libraryRecycler.adapter = ArtistAdapter(
musicModel.artists.value!!,BindingClickListener { artist,itemBinding ->
navToArtist(artist,itemBinding)
}
)
(view?.parent as? ViewGroup)?.doOnPreDraw {
// Parent has been drawn. Start transitioning!
startPostponedEnterTransition()
}
return binding.root
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。