Material-components-android: [motion] Fragment to Activity

Created on 21 Feb 2020  路  12Comments  路  Source: material-components/material-components-android

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?

question

Most helpful comment

@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
  }

All 12 comments

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
  }
Was this page helpful?
0 / 5 - 0 ratings