From c646a4e7ba5c0734662a4e7d372f13ae9384892e Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Wed, 22 Jan 2020 21:52:56 +0100 Subject: [PATCH] Fix rendering title view in native header on Android. (#294) This change removes the behavior that's been added for an unclear reason. We may consider reverting this one, however I was unable to reproduce a problem when setting header title view layout measurements was necessary. To the contrary it was causing issues in the case when the title header view updates. In such a case we would never update width/height so the updated view might be cropped. In addition we are changing the way we schedule native layout updates. Previously we'd use handler.post but it was causing one frame delay so this change migrates us to use choreographer. --- .../swmansion/rnscreens/ScreenContainer.java | 13 +++++++++---- .../rnscreens/ScreenStackHeaderSubview.java | 19 ++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java b/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java index 216ee120..bf2a0ba5 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java @@ -33,6 +33,7 @@ public class ScreenContainer extends ViewGroup { private boolean mIsTransitioning; private boolean mLayoutEnqueued = false; + private final ChoreographerCompat.FrameCallback mFrameCallback = new ChoreographerCompat.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { @@ -40,9 +41,9 @@ public class ScreenContainer extends ViewGroup { } }; - private final Runnable mLayoutRunnable = new Runnable() { + private final ChoreographerCompat.FrameCallback mLayoutCallback = new ChoreographerCompat.FrameCallback() { @Override - public void run() { + public void doFrame(long frameTimeNanos) { mLayoutEnqueued = false; measure( MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), @@ -66,9 +67,13 @@ public class ScreenContainer extends ViewGroup { public void requestLayout() { super.requestLayout(); - if (!mLayoutEnqueued) { + if (!mLayoutEnqueued && mLayoutCallback != null) { mLayoutEnqueued = true; - post(mLayoutRunnable); + // we use NATIVE_ANIMATED_MODULE choreographer queue because it allows us to catch the current + // looper loop instead of enqueueing the update in the next loop causing a one frame delay. + ReactChoreographer.getInstance().postFrameCallback( + ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, + mLayoutCallback); } } diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.java b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.java index 0a0c9e09..36937d24 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.java @@ -43,18 +43,15 @@ public class ScreenStackHeaderSubview extends ReactViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (changed && (mType == Type.CENTER || mType == Type.TITLE)) { + if (changed && (mType == Type.CENTER)) { + // if we want the view to be centered we need to account for the fact that right and left + // paddings may not be equal. Measurements measurements = new Measurements(); - measurements.width = right - left; - if (mType == Type.CENTER) { - // if we want the view to be centered we need to account for the fact that right and left - // paddings may not be equal. - View parent = (View) getParent(); - int parentWidth = parent.getWidth(); - int rightPadding = parentWidth - right; - int leftPadding = left; - measurements.width = Math.max(0, parentWidth - 2 * Math.max(rightPadding, leftPadding)); - } + View parent = (View) getParent(); + int parentWidth = parent.getWidth(); + int rightPadding = parentWidth - right; + int leftPadding = left; + measurements.width = Math.max(0, parentWidth - 2 * Math.max(rightPadding, leftPadding)); measurements.height = bottom - top; mUIManager.setViewLocalData(getId(), measurements); }