Bladeren bron

Support declaring interpolation per shared element transition (#6139)

* Implement startDelay + fix image scale transition

This commit adds support to the startDelay option in shared element transitions on Android. It also fixes image scale transition which only animated the image's scale type, but not its bounds.

* Support declaring interpolator per element transition
Guy Carmeli 4 jaren geleden
bovenliggende
commit
e80eb9275a
No account linked to committer's email address
14 gewijzigde bestanden met toevoegingen van 200 en 31 verwijderingen
  1. 12
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/SharedElementTransitionOptions.java
  2. 20
    0
      lib/android/app/src/main/java/com/reactnativenavigation/utils/Animator.kt
  3. 2
    1
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/SharedElementTransition.kt
  4. 15
    13
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/TransitionAnimatorCreator.kt
  5. 19
    5
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorAnimator.kt
  6. 32
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ClipBoundsAnimator.kt
  7. 42
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ClipBoundsEvaluator.kt
  8. 18
    7
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/MatrixAnimator.kt
  9. 8
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ScaleXAnimator.kt
  10. 8
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ScaleYAnimator.kt
  11. 2
    2
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/TextChangeAnimator.kt
  12. 11
    1
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/XAnimator.kt
  13. 11
    1
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/YAnimator.kt
  14. 0
    1
      playground/src/screens/sharedElementTransition/CocktailDetailsScreen.js

+ 12
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/SharedElementTransitionOptions.java Bestand weergeven

@@ -1,9 +1,11 @@
1 1
 package com.reactnativenavigation.parse;
2 2
 
3
+import com.reactnativenavigation.parse.params.Interpolation;
3 4
 import com.reactnativenavigation.parse.params.NullNumber;
4 5
 import com.reactnativenavigation.parse.params.NullText;
5 6
 import com.reactnativenavigation.parse.params.Number;
6 7
 import com.reactnativenavigation.parse.params.Text;
8
+import com.reactnativenavigation.parse.parsers.InterpolationParser;
7 9
 import com.reactnativenavigation.parse.parsers.NumberParser;
8 10
 import com.reactnativenavigation.parse.parsers.TextParser;
9 11
 
@@ -15,6 +17,8 @@ public class SharedElementTransitionOptions {
15 17
     public Text fromId = new NullText();
16 18
     public Text toId = new NullText();
17 19
     public Number duration = new NullNumber();
20
+    public Number startDelay = new NullNumber();
21
+    public Interpolation interpolation = Interpolation.NO_VALUE;
18 22
 
19 23
     public static SharedElementTransitionOptions parse(@Nullable JSONObject json) {
20 24
         SharedElementTransitionOptions transition = new SharedElementTransitionOptions();
@@ -23,6 +27,8 @@ public class SharedElementTransitionOptions {
23 27
         transition.fromId = TextParser.parse(json, "fromId");
24 28
         transition.toId = TextParser.parse(json, "toId");
25 29
         transition.duration = NumberParser.parse(json, "duration");
30
+        transition.startDelay = NumberParser.parse(json, "startDelay");
31
+        transition.interpolation = InterpolationParser.parse(json, "interpolation");
26 32
 
27 33
         return transition;
28 34
     }
@@ -31,15 +37,21 @@ public class SharedElementTransitionOptions {
31 37
         if (other.fromId.hasValue()) fromId = other.fromId;
32 38
         if (other.toId.hasValue()) toId = other.toId;
33 39
         if (other.duration.hasValue()) duration = other.duration;
40
+        if (other.startDelay.hasValue()) startDelay = other.startDelay;
34 41
     }
35 42
 
36 43
     void mergeWithDefault(SharedElementTransitionOptions defaultOptions) {
37 44
         if (!fromId.hasValue()) fromId = defaultOptions.fromId;
38 45
         if (!toId.hasValue()) toId = defaultOptions.toId;
39 46
         if (!duration.hasValue()) duration = defaultOptions.duration;
47
+        if (!startDelay.hasValue()) startDelay = defaultOptions.startDelay;
40 48
     }
41 49
 
42 50
     public long getDuration() {
43 51
         return duration.get(0).longValue();
44 52
     }
53
+
54
+    public long getStartDelay() {
55
+        return startDelay.get(0).longValue();
56
+    }
45 57
 }

+ 20
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/Animator.kt Bestand weergeven

@@ -0,0 +1,20 @@
1
+package com.reactnativenavigation.utils
2
+
3
+import android.animation.Animator
4
+import android.animation.TimeInterpolator
5
+import android.view.animation.Interpolator
6
+
7
+fun Animator.withStartDelay(delay: Long): Animator {
8
+    startDelay = delay
9
+    return this
10
+}
11
+
12
+fun Animator.withDuration(duration: Long): Animator {
13
+    this.duration = duration
14
+    return this
15
+}
16
+
17
+fun Animator.withInterpolator(interpolator: TimeInterpolator): Animator {
18
+    this.interpolator = interpolator
19
+    return this
20
+}

+ 2
- 1
lib/android/app/src/main/java/com/reactnativenavigation/views/element/SharedElementTransition.kt Bestand weergeven

@@ -30,9 +30,10 @@ class SharedElementTransition(appearing: ViewController<*>, private val options:
30 30
 
31 31
     private fun animators(): List<PropertyAnimatorCreator<*>> {
32 32
         return listOf(
33
+                MatrixAnimator(from, to),
34
+                ClipBoundsAnimator(from, to),
33 35
                 XAnimator(from, to),
34 36
                 YAnimator(from, to),
35
-                MatrixAnimator(from, to),
36 37
                 ScaleXAnimator(from, to),
37 38
                 ScaleYAnimator(from, to),
38 39
                 BackgroundColorAnimator(from, to),

+ 15
- 13
lib/android/app/src/main/java/com/reactnativenavigation/views/element/TransitionAnimatorCreator.kt Bestand weergeven

@@ -9,6 +9,7 @@ import android.widget.FrameLayout
9 9
 import androidx.core.animation.doOnCancel
10 10
 import androidx.core.animation.doOnEnd
11 11
 import com.facebook.react.uimanager.ViewGroupManager
12
+import com.facebook.react.views.image.ReactImageView
12 13
 import com.reactnativenavigation.R
13 14
 import com.reactnativenavigation.parse.AnimationOptions
14 15
 import com.reactnativenavigation.utils.ViewTags
@@ -51,9 +52,7 @@ open class TransitionAnimatorCreator {
51 52
     private fun reparentViews(transitions: TransitionSet) {
52 53
         transitions.transitions
53 54
                 .sortedBy { ViewGroupManager.getViewZIndex(it.view) }
54
-                .forEach {
55
-                    reparent(it)
56
-                }
55
+                .forEach { reparent(it) }
57 56
     }
58 57
 
59 58
     private fun createSharedElementTransitionAnimators(transitions: List<SharedElementTransition>): List<AnimatorSet> {
@@ -65,14 +64,15 @@ open class TransitionAnimatorCreator {
65 64
     }
66 65
 
67 66
     private fun createSharedElementAnimator(transition: SharedElementTransition): AnimatorSet {
68
-        val set = AnimatorSet()
69
-        set.playTogether(transition.createAnimators())
70
-        set.addListener(object : AnimatorListenerAdapter() {
71
-            override fun onAnimationStart(animation: Animator) {
72
-                transition.from.alpha = 0f
73
-            }
74
-        })
75
-        return set
67
+        return transition
68
+                .createAnimators()
69
+                .apply {
70
+                    addListener(object : AnimatorListenerAdapter() {
71
+                        override fun onAnimationStart(animation: Animator) {
72
+                            transition.from.alpha = 0f
73
+                        }
74
+                    })
75
+                }
76 76
     }
77 77
 
78 78
     private fun createElementTransitionAnimators(transitions: List<ElementTransition>): List<AnimatorSet> {
@@ -116,8 +116,10 @@ open class TransitionAnimatorCreator {
116 116
             lp.topMargin = loc.y + viewController.topInset
117 117
             lp.topMargin = loc.y
118 118
             lp.leftMargin = loc.x
119
-            lp.width = view.width
120
-            lp.height = view.height
119
+            if (view !is ReactImageView) {
120
+                lp.width = view.width
121
+                lp.height = view.height
122
+            }
121 123
             view.layoutParams = lp
122 124
             transition.viewController.requireParentController().addOverlay(view)
123 125
         }

+ 19
- 5
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorAnimator.kt Bestand weergeven

@@ -1,14 +1,19 @@
1 1
 package com.reactnativenavigation.views.element.animators
2 2
 
3 3
 import android.animation.Animator
4
+import android.animation.AnimatorListenerAdapter
4 5
 import android.animation.ObjectAnimator
5 6
 import android.view.View
6 7
 import android.view.ViewGroup
8
+import androidx.core.animation.addListener
9
+import androidx.core.animation.doOnStart
7 10
 import com.facebook.react.views.text.ReactTextView
8 11
 import com.facebook.react.views.view.ReactViewBackgroundDrawable
9 12
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
10 13
 import com.reactnativenavigation.utils.ColorUtils
11 14
 import com.reactnativenavigation.utils.ViewUtils
15
+import com.reactnativenavigation.utils.withInterpolator
16
+import com.reactnativenavigation.utils.withStartDelay
12 17
 
13 18
 class BackgroundColorAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(from, to) {
14 19
     override fun shouldAnimateProperty(fromChild: ViewGroup, toChild: ViewGroup): Boolean {
@@ -19,10 +24,19 @@ class BackgroundColorAnimator(from: View, to: View) : PropertyAnimatorCreator<Vi
19 24
     override fun excludedViews() = listOf(ReactTextView::class.java)
20 25
 
21 26
     override fun create(options: SharedElementTransitionOptions): Animator {
22
-        return ObjectAnimator.ofObject(
23
-                BackgroundColorEvaluator(to.background as ReactViewBackgroundDrawable),
24
-                ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(from)),
25
-                ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(to))
26
-        ).setDuration(options.getDuration())
27
+        val backgroundColorEvaluator = BackgroundColorEvaluator(to.background as ReactViewBackgroundDrawable)
28
+        val fromColor = ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(from))
29
+        val toColor = ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(to))
30
+
31
+        backgroundColorEvaluator.evaluate(0f, fromColor, toColor)
32
+        return ObjectAnimator
33
+                .ofObject(
34
+                        backgroundColorEvaluator,
35
+                        fromColor,
36
+                        toColor
37
+                )
38
+                .setDuration(options.getDuration())
39
+                .withStartDelay(options.getStartDelay())
40
+                .withInterpolator(options.interpolation.interpolator)
27 41
     }
28 42
 }

+ 32
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ClipBoundsAnimator.kt Bestand weergeven

@@ -0,0 +1,32 @@
1
+package com.reactnativenavigation.views.element.animators
2
+
3
+import android.animation.Animator
4
+import android.animation.ObjectAnimator
5
+import android.graphics.Rect
6
+import android.view.View
7
+import com.facebook.react.views.image.ReactImageView
8
+import com.reactnativenavigation.parse.SharedElementTransitionOptions
9
+import com.reactnativenavigation.utils.ViewUtils
10
+import com.reactnativenavigation.utils.withDuration
11
+import com.reactnativenavigation.utils.withInterpolator
12
+import com.reactnativenavigation.utils.withStartDelay
13
+
14
+class ClipBoundsAnimator(from: View, to: View) : PropertyAnimatorCreator<ReactImageView>(from, to) {
15
+    override fun shouldAnimateProperty(fromChild: ReactImageView, toChild: ReactImageView): Boolean {
16
+        return !ViewUtils.areDimensionsEqual(from, to)
17
+    }
18
+
19
+    override fun create(options: SharedElementTransitionOptions): Animator {
20
+        val startDrawingRect = Rect(); from.getDrawingRect(startDrawingRect)
21
+        val endDrawingRect = Rect(); to.getDrawingRect(endDrawingRect)
22
+        return ObjectAnimator.ofObject(
23
+                ClipBoundsEvaluator(),
24
+                startDrawingRect,
25
+                endDrawingRect
26
+        )
27
+                .setDuration(options.getDuration())
28
+                .withStartDelay(options.getStartDelay())
29
+                .withInterpolator(options.interpolation.interpolator)
30
+    }
31
+
32
+}

+ 42
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ClipBoundsEvaluator.kt Bestand weergeven

@@ -0,0 +1,42 @@
1
+package com.reactnativenavigation.views.element.animators
2
+
3
+import android.animation.TypeEvaluator
4
+import android.graphics.Rect
5
+
6
+class ClipBoundsEvaluator : TypeEvaluator<Rect> {
7
+    private var fromWidth = 0
8
+    private var fromHeight = 0
9
+    private var toWidth = 0
10
+    private var toHeight = 0
11
+    private val result = Rect()
12
+
13
+    override fun evaluate(ratio: Float, from: Rect, to: Rect): Rect {
14
+        sync(from, to)
15
+        if (toHeight == fromHeight) {
16
+            result.bottom = toHeight
17
+        } else {
18
+            if (toHeight > fromHeight) {
19
+                result.bottom = (toHeight - (toHeight - fromHeight) * (1 - ratio)).toInt()
20
+            } else {
21
+                result.bottom = (toHeight + (fromHeight - toHeight) * (1 - ratio)).toInt()
22
+            }
23
+        }
24
+        if (toWidth == fromWidth) {
25
+            result.right = toWidth
26
+        } else {
27
+            if (toWidth > fromWidth) {
28
+                result.right = (toWidth - (toWidth - fromWidth) * (1 - ratio)).toInt()
29
+            } else {
30
+                result.right = (toWidth + (fromWidth - toWidth) * (1 - ratio)).toInt()
31
+            }
32
+        }
33
+        return result
34
+    }
35
+
36
+    private fun sync(from: Rect, to: Rect) {
37
+        fromWidth = from.right
38
+        fromHeight = from.bottom
39
+        toWidth = to.right
40
+        toHeight = to.bottom
41
+    }
42
+}

+ 18
- 7
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/MatrixAnimator.kt Bestand weergeven

@@ -1,14 +1,20 @@
1 1
 package com.reactnativenavigation.views.element.animators
2 2
 
3 3
 import android.animation.Animator
4
+import android.animation.AnimatorListenerAdapter
4 5
 import android.animation.ObjectAnimator
5 6
 import android.animation.TypeEvaluator
6 7
 import android.graphics.Rect
7 8
 import android.view.View
9
+import androidx.core.animation.addListener
10
+import androidx.core.animation.doOnStart
8 11
 import com.facebook.drawee.drawable.ScalingUtils.InterpolatingScaleType
9 12
 import com.facebook.react.views.image.ReactImageView
10 13
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
11 14
 import com.reactnativenavigation.utils.ViewUtils
15
+import com.reactnativenavigation.utils.withDuration
16
+import com.reactnativenavigation.utils.withInterpolator
17
+import com.reactnativenavigation.utils.withStartDelay
12 18
 
13 19
 class MatrixAnimator(from: View, to: View) : PropertyAnimatorCreator<ReactImageView>(from, to) {
14 20
     override fun shouldAnimateProperty(fromChild: ReactImageView, toChild: ReactImageView): Boolean {
@@ -23,13 +29,18 @@ class MatrixAnimator(from: View, to: View) : PropertyAnimatorCreator<ReactImageV
23 29
                     calculateBounds(from),
24 30
                     calculateBounds(to)
25 31
             )
26
-            return ObjectAnimator.ofObject(TypeEvaluator<Float> { fraction: Float, _: Any, _: Any ->
27
-                hierarchy.actualImageScaleType?.let {
28
-                    (hierarchy.actualImageScaleType as InterpolatingScaleType?)!!.value = fraction
29
-                    to.invalidate()
30
-                }
31
-                null
32
-            }, 0, 1).setDuration(options.getDuration())
32
+
33
+            return ObjectAnimator
34
+                    .ofObject(TypeEvaluator<Float> { fraction: Float, _: Any, _: Any ->
35
+                        hierarchy.actualImageScaleType?.let {
36
+                            (hierarchy.actualImageScaleType as InterpolatingScaleType?)!!.value = fraction
37
+                            to.invalidate()
38
+                        }
39
+                        null
40
+                    }, 0, 1)
41
+                    .setDuration(options.getDuration())
42
+                    .withStartDelay(options.getStartDelay())
43
+                    .withInterpolator(options.interpolation.interpolator)
33 44
         }
34 45
     }
35 46
 

+ 8
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ScaleXAnimator.kt Bestand weergeven

@@ -4,8 +4,13 @@ import android.animation.Animator
4 4
 import android.animation.ObjectAnimator
5 5
 import android.view.View
6 6
 import android.view.ViewGroup
7
+import androidx.core.animation.addListener
8
+import androidx.core.animation.doOnStart
7 9
 import com.facebook.react.views.text.ReactTextView
8 10
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
11
+import com.reactnativenavigation.utils.withDuration
12
+import com.reactnativenavigation.utils.withInterpolator
13
+import com.reactnativenavigation.utils.withStartDelay
9 14
 
10 15
 class ScaleXAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(from, to) {
11 16
     override fun shouldAnimateProperty(fromChild: ViewGroup, toChild: ViewGroup): Boolean {
@@ -15,8 +20,11 @@ class ScaleXAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(
15 20
     override fun excludedViews(): List<Class<*>> = listOf<Class<*>>(ReactTextView::class.java)
16 21
 
17 22
     override fun create(options: SharedElementTransitionOptions): Animator {
23
+        to.scaleX = from.width.toFloat() / to.width
18 24
         return ObjectAnimator
19 25
                 .ofFloat(to, View.SCALE_X, from.width.toFloat() / to.width, 1f)
20 26
                 .setDuration(options.getDuration())
27
+                .withStartDelay(options.getStartDelay())
28
+                .withInterpolator(options.interpolation.interpolator)
21 29
     }
22 30
 }

+ 8
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/ScaleYAnimator.kt Bestand weergeven

@@ -4,8 +4,13 @@ import android.animation.Animator
4 4
 import android.animation.ObjectAnimator
5 5
 import android.view.View
6 6
 import android.view.ViewGroup
7
+import androidx.core.animation.addListener
8
+import androidx.core.animation.doOnStart
7 9
 import com.facebook.react.views.text.ReactTextView
8 10
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
11
+import com.reactnativenavigation.utils.withDuration
12
+import com.reactnativenavigation.utils.withInterpolator
13
+import com.reactnativenavigation.utils.withStartDelay
9 14
 
10 15
 class ScaleYAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(from, to) {
11 16
     override fun shouldAnimateProperty(fromChild: ViewGroup, toChild: ViewGroup): Boolean {
@@ -15,8 +20,11 @@ class ScaleYAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(
15 20
     override fun excludedViews() = listOf(ReactTextView::class.java)
16 21
 
17 22
     override fun create(options: SharedElementTransitionOptions): Animator {
23
+        to.scaleY = from.height.toFloat() / to.height
18 24
         return ObjectAnimator
19 25
                 .ofFloat(to, View.SCALE_Y, from.height.toFloat() / to.height, 1f)
20 26
                 .setDuration(options.getDuration())
27
+                .withStartDelay(options.getStartDelay())
28
+                .withInterpolator(options.interpolation.interpolator)
21 29
     }
22 30
 }

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/TextChangeAnimator.kt Bestand weergeven

@@ -7,8 +7,7 @@ import android.view.ViewGroup
7 7
 import android.widget.TextView
8 8
 import com.facebook.react.views.text.ReactTextView
9 9
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
10
-import com.reactnativenavigation.utils.TextViewUtils
11
-import com.reactnativenavigation.utils.ViewUtils
10
+import com.reactnativenavigation.utils.*
12 11
 import com.shazam.android.widget.text.reflow.ReflowTextAnimatorHelper
13 12
 
14 13
 class TextChangeAnimator(from: View, to: View) : PropertyAnimatorCreator<ReactTextView>(from, to) {
@@ -39,5 +38,6 @@ class TextChangeAnimator(from: View, to: View) : PropertyAnimatorCreator<ReactTe
39 38
                 }
40 39
                 .buildAnimator()
41 40
                 .setDuration(options.getDuration())
41
+                .withInterpolator(options.interpolation.interpolator)
42 42
     }
43 43
 }

+ 11
- 1
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/XAnimator.kt Bestand weergeven

@@ -1,12 +1,17 @@
1 1
 package com.reactnativenavigation.views.element.animators
2 2
 
3 3
 import android.animation.Animator
4
+import android.animation.AnimatorListenerAdapter
4 5
 import android.animation.ObjectAnimator
5 6
 import android.view.View
6 7
 import android.view.View.TRANSLATION_X
8
+import androidx.core.animation.addListener
9
+import androidx.core.animation.doOnStart
7 10
 import com.facebook.react.views.text.ReactTextView
8 11
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
9 12
 import com.reactnativenavigation.utils.ViewUtils
13
+import com.reactnativenavigation.utils.withInterpolator
14
+import com.reactnativenavigation.utils.withStartDelay
10 15
 
11 16
 class XAnimator(from: View, to: View) : PropertyAnimatorCreator<View>(from, to) {
12 17
     private val dx: Int
@@ -23,6 +28,11 @@ class XAnimator(from: View, to: View) : PropertyAnimatorCreator<View>(from, to)
23 28
     override fun shouldAnimateProperty(fromChild: View, toChild: View) = dx != 0
24 29
 
25 30
     override fun create(options: SharedElementTransitionOptions): Animator {
26
-        return ObjectAnimator.ofFloat(to, TRANSLATION_X, dx.toFloat(), 0f).setDuration(options.getDuration())
31
+        to.translationX = dx.toFloat()
32
+        return ObjectAnimator
33
+                .ofFloat(to, TRANSLATION_X, dx.toFloat(), 0f)
34
+                .setDuration(options.getDuration())
35
+                .withStartDelay(options.getStartDelay())
36
+                .withInterpolator(options.interpolation.interpolator)
27 37
     }
28 38
 }

+ 11
- 1
lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/YAnimator.kt Bestand weergeven

@@ -1,13 +1,18 @@
1 1
 package com.reactnativenavigation.views.element.animators
2 2
 
3 3
 import android.animation.Animator
4
+import android.animation.AnimatorListenerAdapter
4 5
 import android.animation.ObjectAnimator
5 6
 import android.view.View
6 7
 import android.view.View.TRANSLATION_Y
7 8
 import android.view.ViewGroup
9
+import androidx.core.animation.addListener
10
+import androidx.core.animation.doOnStart
8 11
 import com.facebook.react.views.text.ReactTextView
9 12
 import com.reactnativenavigation.parse.SharedElementTransitionOptions
10 13
 import com.reactnativenavigation.utils.ViewUtils
14
+import com.reactnativenavigation.utils.withInterpolator
15
+import com.reactnativenavigation.utils.withStartDelay
11 16
 
12 17
 class YAnimator(from: View, to: View) : PropertyAnimatorCreator<View>(from, to) {
13 18
     private val dy: Int
@@ -24,6 +29,11 @@ class YAnimator(from: View, to: View) : PropertyAnimatorCreator<View>(from, to)
24 29
     override fun excludedViews() = listOf(ReactTextView::class.java)
25 30
 
26 31
     override fun create(options: SharedElementTransitionOptions): Animator {
27
-        return ObjectAnimator.ofFloat(to, TRANSLATION_Y, dy.toFloat(), 0f).setDuration(options.getDuration())
32
+        to.translationY = dy.toFloat()
33
+        return ObjectAnimator
34
+                .ofFloat(to, TRANSLATION_Y, dy.toFloat(), 0f)
35
+                .setDuration(options.getDuration())
36
+                .withStartDelay(options.getStartDelay())
37
+                .withInterpolator(options.interpolation.interpolator)
28 38
     }
29 39
 }

+ 0
- 1
playground/src/screens/sharedElementTransition/CocktailDetailsScreen.js Bestand weergeven

@@ -45,7 +45,6 @@ class CocktailDetailsScreen extends React.Component {
45 45
 module.exports = CocktailDetailsScreen;
46 46
 const SIZE = 120;
47 47
 const HEADER = 150;
48
-const IMAGE_OFFSET = 52
49 48
 const styles = StyleSheet.create({
50 49
   root: {
51 50
     marginTop: 0