hi in https://material.io/develop/android/theming/motion/
Explained about
Container transform Transition between Fragments
or
Container transform Transition between Activities
But you didn't say anything about Container transform Transition between Fragment to Activity !
How should it be implemented?
Hey there.
You can transition from a Fragment to an Activity basically the same way you'd transition from an Activity to an Activity since a Fragment can be thought of as just a view hierarchy inside of an Activity.
For example, to implement a container transform from FragmentA in ActivityA to ActivityB, follow the same steps in Container transform: Transition between Activities, setting up both ActivityA and ActivityB by enabling transitions, adding the shared element callbacks, etc.
Then, in FragmentA, when you're ready to container transform to ActivityB, call startActivity with the same ActivityOptions as written in the Motion documentation but pass in the View in FragmentA from which you are transitioning.
Let me know how this works for you.
Going ahead and closing this but feel free to re-open if you feel it hasn't been answered.
@hunterstich
i add in ActivityA
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementsUseOverlay = false
super.onCreate(savedInstanceState)
and activityB
//for Transition
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
findViewById<View>(android.R.id.content).transitionName = "shared_element_container"
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = MaterialContainerTransform(this)
window.sharedElementReturnTransition = MaterialContainerTransform(this)
super.onCreate(savedInstanceState)
and fragmentA
fun goDetailNews2(view: View, news: News?, activity: Activity) {
val intent = Intent(BaseApp.context, NewsDetailActivity::class.java)
intent.putExtra("news", news)
val options = ActivityOptions.makeSceneTransitionAnimation(
activity,
view,
"shared_element_container" // The transition name to be matched in Activity B.
)
activity.startActivity(intent, options.toBundle())
}
and set xml item
android:transitionName="shared_element_container"
The error happened!
java.lang.IllegalArgumentException: negative durations are not allowed
at com.android.internal.policy.impl.PhoneWindow.setTransitionBackgroundFadeDuration(PhoneWindow.java:4391)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.updateBackgroundFadeDuration(MaterialContainerTransformSharedElementCallback.java:228)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.setUpEnterTransform(MaterialContainerTransformSharedElementCallback.java:168)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.onMapSharedElements(MaterialContainerTransformSharedElementCallback.java:89)
You need to set a duration (using Transition#setDuration) or Transition (the class that MaterialContainerTransform extends from) will revert to a value of -1 (or no duration):
MaterialContainerTransform transform = MaterialContainerTransform(this)
.setDuration(/* a duration in long (e.g. 300L or 275L) */);
This behaviour is documented in the Transition#setDuration method:
Sets the duration of this transition. By default, there is no duration (indicated by a negative number), which means that the Animator created by the transition will have its own specified duration. If the duration of a Transition is set, that duration will override the Animator duration.
(P.S. Is this a bug or is it intentional?)
@EdricChan03
i add in FragmentA
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedElementEnterTransition = MaterialContainerTransform(requireContext()).setDuration(300L)
}
Again have error
java.lang.IllegalArgumentException: negative durations are not allowed
at com.android.internal.policy.impl.PhoneWindow.setTransitionBackgroundFadeDuration(PhoneWindow.java:4391)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.updateBackgroundFadeDuration(MaterialContainerTransformSharedElementCallback.java:228)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.setUpEnterTransform(MaterialContainerTransformSharedElementCallback.java:168)
at com.google.android.material.transition.MaterialContainerTransformSharedElementCallback.onMapSharedElements(MaterialContainerTransformSharedElementCallback.java:89)
Could you try removing the L suffix from the duration?
remove it but Again have top error
sharedElementEnterTransition = MaterialContainerTransform(requireContext()).setDuration(300)
im debug function updateBackgroundFadeDuration in MaterialContainerTransformSharedElementCallback Duration Had two reference it first 300 but two is -1
Did you set it as well in activity B?
yes
override fun onCreate(savedInstanceState: Bundle?) {
//for Transition
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
val transform = MaterialContainerTransform(this)
transform.duration = 300
window.sharedElementEnterTransition = transform
findViewById<View>(android.R.id.content).transitionName = "shared_element_container"
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = MaterialContainerTransform(this)
window.sharedElementReturnTransition = MaterialContainerTransform(this)
super.onCreate(savedInstanceState)
oh fix this error with this code in ActivityB
//for Transition
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
val transform = MaterialContainerTransform(this)
transform.duration = 300
window.sharedElementEnterTransition = transform
findViewById<View>(android.R.id.content).transitionName = "shared_element_container"
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = transform
window.sharedElementReturnTransition = transform
super.onCreate(savedInstanceState)
but Another bug found!
java.lang.IllegalArgumentException: 16908290 not a valid ancestor
at com.google.android.material.transition.TransitionUtils.findAncestorById(TransitionUtils.java:204)
at com.google.android.material.transition.MaterialContainerTransform.createAnimator(MaterialContainerTransform.java:713)
at android.transition.Transition.createAnimators(Transition.java:723)
at android.transition.TransitionSet.createAnimators(TransitionSet.java:405)
at android.transition.TransitionSet.createAnimators(TransitionSet.java:405)
at android.transition.TransitionSet.createAnimators(TransitionSet.java:405)
at android.transition.Transition.playTransition(Transition.java:1761)
at android.transition.TransitionManager$MultiListener.onPreDraw(TransitionManager.java:298)
@flashiran1 Apologies for the delayed response.
Try setting a target on ActivityB's enter shared element transition like:
window.sharedElementEnterTransition = MaterialContainerTransform(this).apply {
addTarget(android.R.id.content)
duration = 300L
}
Most helpful comment
@flashiran1 Apologies for the delayed response.
Try setting a target on ActivityB's enter shared element transition like: