I have a SharedElementTransition on an image, which goes from a recyclerview in fragment A to a CollapsingToolbarLayout in fragment B. I tried everything I thought of in order to have a clean transition, however each time it fails.
class DetailsFragment : Fragment(R.layout.fragment_details) {
private var _binding: FragmentDetailsBinding? = null
private val binding get() = _binding!!
private val args: DetailsFragmentArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentDetailsBinding.bind(view)
val animation = TransitionInflater.from(requireContext()).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = animation
Glide.with(this)
.load(args.show.imageUrl)
.error(R.drawable.default_image)
.into(binding.detailsShowImage)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
As it is, the image loads while the transition is executing, and there's a split moment where the image is white (there's none) and then the image is loaded. My goal here is to remove this 'white image'.
I tried to use a listener with Glide and postpone the transition with postponeEnterTransition() like so:
Glide.with(this)
.load(args.show.imageUrl)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
startPostponeEnterTransition()
return true
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean
startPostponeEnterTransition()
return true
}
})
.error(R.drawable.default_image)
.into(binding.detailsShowImage)
However, with a very slow internet connexion, the image takes too long to load, which causes the transition to be delayed by sometimes several seconds. I tried putting a timeout with Glide's .timeout(TIMEOUT) but that still didn't work.
I may have done something wrong with my previous approach, and if so I'd be glad to hear the answer to my problem. But since I didn't find any, I switched to another approach, which is to modify the enter transition in order to modify the second image only when the transition ends (and if the image hasn't finished loading, to display a placeholder).
So I tried modifying the move transition provided by Android in order to keep the first image until the end of the transition, but I couldn't find how to achieve that.
I saw that the move transition uses the below 4 transitions:
<transitionSet>
<changeBounds/>
<changeTransform/>
<changeClipBounds/>
<changeImageTransform/>
</transitionSet>
But my poor knowledge of transitions prevented me from knowing what to change in here, except from trying to remove them one by one hoping it does what I want...to which the answer is of course no. So here I am hoping for some insights on how to have a smooth and good-looking transition.
I can provide you with a solution but can't give you more information on animations/transitions.
So, in the Recylcer view also, it is pretty obvious that you are Glide to load the images. If you use the very same listener in the recycler view but instead store the drawable it provides and send it to the other activity using another class, it wont give you any issues. This is the code:
And now the
ObjectsHelperclassAnd finally in the second activity's
onCreate()method:This shouldnt give you any errors.