aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2019-10-28 19:54:57 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-10-28 19:54:57 +0000
commit7bcd90e2242cf8be3e48f8138a88b17d17e0e93b (patch)
tree0d8c70eb3fa9cdcaa7449527578f7a6b31e0e00c
parent6751e9436edb2224b36c05871bcb8dd88538b0e6 (diff)
parentcf08568adc4e38b98329533b9b5246d172f04868 (diff)
downloadsupport-7bcd90e2242cf8be3e48f8138a88b17d17e0e93b.tar.gz
Merge "Fix fragment transition epicenter calculation" into androidx-master-dev
-rw-r--r--fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransitionImpl.java31
-rw-r--r--transition/transition/src/androidTest/java/androidx/transition/EpicenterTest.kt102
2 files changed, 130 insertions, 3 deletions
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransitionImpl.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransitionImpl.java
index 4cb1f3462bd..4e4a7f75879 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransitionImpl.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransitionImpl.java
@@ -20,8 +20,10 @@ import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import android.annotation.SuppressLint;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
@@ -77,9 +79,32 @@ public abstract class FragmentTransitionImpl {
* containing the bounds relative to the screen that the view is in.
*/
protected void getBoundsOnScreen(View view, Rect epicenter) {
- int[] loc = new int[2];
- view.getLocationOnScreen(loc);
- epicenter.set(loc[0], loc[1], loc[0] + view.getWidth(), loc[1] + view.getHeight());
+ if (!ViewCompat.isAttachedToWindow(view)) {
+ return;
+ }
+
+ final RectF rect = new RectF();
+ rect.set(0, 0, view.getWidth(), view.getHeight());
+
+ view.getMatrix().mapRect(rect);
+ rect.offset(view.getLeft(), view.getTop());
+
+ ViewParent parent = view.getParent();
+ while (parent instanceof View) {
+ View parentView = (View) parent;
+
+ rect.offset(-parentView.getScrollX(), -parentView.getScrollY());
+ parentView.getMatrix().mapRect(rect);
+ rect.offset(parentView.getLeft(), parentView.getTop());
+
+ parent = parentView.getParent();
+ }
+
+ final int[] loc = new int[2];
+ view.getRootView().getLocationOnScreen(loc);
+ rect.offset(loc[0], loc[1]);
+ epicenter.set(Math.round(rect.left), Math.round(rect.top), Math.round(rect.right),
+ Math.round(rect.bottom));
}
/**
diff --git a/transition/transition/src/androidTest/java/androidx/transition/EpicenterTest.kt b/transition/transition/src/androidTest/java/androidx/transition/EpicenterTest.kt
new file mode 100644
index 00000000000..9360122a8f3
--- /dev/null
+++ b/transition/transition/src/androidTest/java/androidx/transition/EpicenterTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.transition
+
+import android.graphics.Rect
+import android.graphics.RectF
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EpicenterTest : BaseTest() {
+
+ @Test
+ fun defaultEpicenter() {
+ testViewEpicenter {}
+ }
+
+ @Test
+ fun rotatedViewEpicenter() {
+ testViewEpicenter {
+ rotation = 180f
+ }
+ }
+
+ @Test
+ fun scaledPivotEpicenter() {
+ testViewEpicenter {
+ pivotX = width.toFloat()
+ pivotY = height.toFloat()
+ scaleX = 0.5f
+ scaleY = 0.5f
+ }
+ }
+
+ private fun testViewEpicenter(viewSetup: View.() -> Unit) {
+ val view = setupTestView()
+ view.viewSetup()
+ val transitionSupport = FragmentTransitionSupport()
+
+ val transition = AutoTransition()
+ transitionSupport.setEpicenter(transition, view)
+
+ val rect = RectF(0f, 0f, view.width.toFloat(), view.height.toFloat())
+ view.matrix.mapRect(rect)
+
+ rect.offset(view.left.toFloat(), view.top.toFloat())
+ val (parentX, parentY) = IntArray(2).apply {
+ (view.parent as View).getLocationOnScreen(this)
+ }
+ rect.offset(parentX.toFloat(), parentY.toFloat())
+
+ val expected = Rect().also {
+ rect.round(it)
+ }
+
+ assertThat(transition.epicenter).isEqualTo(expected)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ (view.parent as ViewGroup).removeView(view)
+ }
+ }
+
+ /**
+ * Returns a view of size 100x100 located at (50, 50)
+ */
+ private fun setupTestView(): View {
+ val view = View(rule.activity)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ rule.activity.root.addView(view, FrameLayout.LayoutParams(100, 100)
+ .apply {
+ leftMargin = 50
+ topMargin = 50
+ })
+ view.left = 50
+ view.top = 50
+ view.right = 150
+ view.bottom = 150
+ }
+ return view
+ }
+} \ No newline at end of file