From c75adb067140893690382b465b4ac728f897c343 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 13 Mar 2018 03:06:42 -0700 Subject: [PATCH] solves the Android pixel bug Summary: emilsjolander hi, this PR solves the following common and probable layout pixel scenario: the older code is presented for reference: ```java view.measure( View.MeasureSpec.makeMeasureSpec( Math.round(node.getLayoutWidth()), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec( Math.round(node.getLayoutHeight()), View.MeasureSpec.EXACTLY)); view.layout( Math.round(xOffset + node.getLayoutX()), Math.round(yOffset + node.getLayoutY()), Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()), Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight())); ``` suppose now the following: - `xOffset + node.getLayoutX() = 2.2` - `node.getLayoutWidth() = 0.4` ==> `Math.round(node.getLayoutWidth()) = 0` - `Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()) = Math.round(2.2 + 0.4) = 3` this induces, the following measurements: ```java view.measure( View.MeasureSpec.makeMeasureSpec( 0, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec( Math.round(node.getLayoutHeight()), View.MeasureSpec.EXACTLY)); view.layout( 2, Math.round(yOffset + node.getLayoutY()), 3, Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight())); ``` the width measurement of the view is 0, while the layout is `(3 - 2 = 1)`. my proposed solution is to measure the view the way it is now, but when layouting I use the `#getMeasuredWidth/Height()` methods, this will stop this problem from happening. I also want to note that this bug happens with high probability. Closes https://github.com/facebook/yoga/pull/712 Reviewed By: emilsjolander Differential Revision: D7231798 Pulled By: priteshrnandgaonkar fbshipit-source-id: 171da519639dbecd75416a574bccc4456aa22f31 --- .../com/facebook/yoga/android/YogaLayout.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java index 5801fbad..90d61af8 100644 --- a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java +++ b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java @@ -7,9 +7,6 @@ package com.facebook.yoga.android; -import java.util.HashMap; -import java.util.Map; - import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; @@ -21,9 +18,6 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; -import android.util.Log; - -import com.facebook.yoga.android.R; import com.facebook.yoga.YogaAlign; import com.facebook.yoga.YogaConstants; import com.facebook.yoga.YogaDirection; @@ -35,10 +29,11 @@ import com.facebook.yoga.YogaMeasureFunction; import com.facebook.yoga.YogaMeasureMode; import com.facebook.yoga.YogaMeasureOutput; import com.facebook.yoga.YogaNode; -import com.facebook.yoga.YogaNode; import com.facebook.yoga.YogaOverflow; import com.facebook.yoga.YogaPositionType; import com.facebook.yoga.YogaWrap; +import java.util.HashMap; +import java.util.Map; /** * A {@code ViewGroup} based on the Yoga layout engine. @@ -291,6 +286,8 @@ public class YogaLayout extends ViewGroup { if (view.getVisibility() == GONE) { return; } + int left = Math.round(xOffset + node.getLayoutX()); + int top = Math.round(yOffset + node.getLayoutY()); view.measure( View.MeasureSpec.makeMeasureSpec( Math.round(node.getLayoutWidth()), @@ -298,11 +295,7 @@ public class YogaLayout extends ViewGroup { View.MeasureSpec.makeMeasureSpec( Math.round(node.getLayoutHeight()), View.MeasureSpec.EXACTLY)); - view.layout( - Math.round(xOffset + node.getLayoutX()), - Math.round(yOffset + node.getLayoutY()), - Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()), - Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight())); + view.layout(left, top, left + view.getMeasuredWidth(), top + view.getMeasuredHeight()); } final int childrenCount = node.getChildCount();