I usually solve problems by myself but this time im really getting mad and can't find proper fix.
Scenario:
I have two fragments let's say A and B.
In Fragment A I'm populating RecyclerView (later only RV) from Rest API.
In Fragment B I have "detail view" with CollapsingToolbarLayout.
When I click on item in RV I'm opening Fragment B with transition and one shared element which is AppCompatImageView where I set local drawable. In Fragment B is image inside CollapsingToolbarLayout.
Shared element transition works in Fragment B - image is moved correctly. Transition also works when I click on back button and image is moving back on it's original position in RV.
But here comes a problem which i can't resolve. In both Fragments that particular image is being stuck on position and when I'm scrolled RV or CollapsingToolbarLayout View is not changed - in Fragment A image is not moving when scrolling RV and in Fragment B image is not hiding on collapse/expand changes.
Do anybody faced this issue because i don't and really don't understand that kind of behaviour. Never happened to me after years of development.
Here is screenshot of Fragment A after going back from Fragment B:
Here i am executing fragment transaction with transition:
fun replaceFragmentWithTransition(context: Context,
sharedElement: View,
fm: FragmentManager?,
layoutContainer: Int,
fragment: Fragment,
tag: String,
addToBackStack: Boolean = false) {
fragment.sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(R.transition.default_transition)
fragment.sharedElementReturnTransition = TransitionInflater.from(context).inflateTransition(R.transition.default_transition)
val ft = fm?.beginTransaction()
ft?.addSharedElement(sharedElement, sharedElement.transitionName)
if (addToBackStack) { ft?.addToBackStack(null) }
ft?.replace(layoutContainer, fragment, tag)
ft?.commit()
}
Here I'm setting return transition callback in Fragment A (called in onViewCreated):
setExitSharedElementCallback(object: SharedElementCallback() {
override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) {
Timber.d("onMapSharedElements")
val vh = recyclerView.findViewHolderForAdapterPosition(selectedPanelIndex)
if (vh != null && sharedElements != null && names != null) {
Timber.d("Size: ${sharedElements.size}")
sharedElements[names[0]] = vh.itemView.findViewById(R.id.imagePanel)
}
}
})
Same in Fragment B but enter transition (called in onViewCreated):
setEnterSharedElementCallback(object: SharedElementCallback() {
override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) {
Timber.d("onMapSharedElements")
if (names != null && sharedElements != null) {
Timber.d("Size: ${sharedElements.size}")
sharedElements[names[0]] = imagePanel
}
}
})
In Fragment B also I assign transitionName into ImageView in onViewCreated function:
imagePanel.transitionName = transitionName
And also setting dynamic transition name in RV adapter:
inner class MyViewModel(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bind(item: Panel, callback: (Panel, View) -> Unit) {
imagePanel.transitionName = "${containerView.context.getString(R.string.text_transition_name_panel_img)}_$adapterPosition"
item.getDrawableFromType().takeIf { it > 0 }?.let {
imagePanel?.setImageDrawable(containerView.context.getDrawableCompat(it))
imagePanel.show()
} ?: imagePanel.hide()
textName?.text = item.name
containerView.onClick { callback(item, imagePanel) }
}
}
Device: Google Pixel 3, Android 10
Note that if i don't use transition callbacks return transition not working but issue with enter transition in Fragment B remains same.
I feel lost in this case. Any help will be appreciated. I tried many things. Thanks.
Update!:
Seems this issue is related to Android 10 only! I tried my old Xiaomi and it works. I created issue here so hope it will be solved. It's really annoying. I will keep updates in this one.