diff options
| author | 2013-01-23 18:46:25 -0800 | |
|---|---|---|
| committer | 2013-01-25 18:43:42 -0800 | |
| commit | 306fe5cc0e85e8a5ef07ff64493982f99caeba3a (patch) | |
| tree | 2240b1d888ba450443cf1b057e80b69e565ad035 | |
| parent | b9781fe08c5b1afba086857aa18b46862550ae88 (diff) | |
Fix bug #8051633 Recent Apps thumbnails in RTL mode (Arabic / Hebrew / Farsi) should be aligned
Basically RelativeLayout was broken in a very stubtle way.
RelativeLayout needs in onMeasure() to have a width in RTL mode when "myWidth=-1" (meaning "not
defined") so that the rest of the onMeasure() computation can be done (children positioning and
width computation).
As there is no way to get its width apart from running the code, in RTL mode we set its width
arbitrary to the screen width for doing the width computation and children positoning.
Then, as a last pass, we will update and fix the children position (no need to do anything with
the computed width because it is correctly computed  already).
Change-Id: I426af3327160e751ef63ed3845aad5bab6dad661
| -rw-r--r-- | core/java/android/widget/RelativeLayout.java | 69 | 
1 files changed, 39 insertions, 30 deletions
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 2b7e162d3b9e..dbeb26dbe349 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -37,6 +37,7 @@ import android.view.Gravity;  import android.view.View;  import android.view.ViewDebug;  import android.view.ViewGroup; +import android.view.WindowManager;  import android.view.accessibility.AccessibilityEvent;  import android.view.accessibility.AccessibilityNodeInfo;  import android.widget.RemoteViews.RemoteView; @@ -220,10 +221,13 @@ public class RelativeLayout extends ViewGroup {      // Some apps came to rely on them. :(      private boolean mAllowBrokenMeasureSpecs = false; +    private int mDisplayWidth; +      public RelativeLayout(Context context) {          super(context);          mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=                  Build.VERSION_CODES.JELLY_BEAN_MR1; +        getDisplayWidth();      }      public RelativeLayout(Context context, AttributeSet attrs) { @@ -231,6 +235,7 @@ public class RelativeLayout extends ViewGroup {          initFromAttributes(context, attrs);          mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=                  Build.VERSION_CODES.JELLY_BEAN_MR1; +        getDisplayWidth();      }      public RelativeLayout(Context context, AttributeSet attrs, int defStyle) { @@ -238,6 +243,7 @@ public class RelativeLayout extends ViewGroup {          initFromAttributes(context, attrs);          mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=                  Build.VERSION_CODES.JELLY_BEAN_MR1; +        getDisplayWidth();      }      private void initFromAttributes(Context context, AttributeSet attrs) { @@ -247,6 +253,11 @@ public class RelativeLayout extends ViewGroup {          a.recycle();      } +    private void getDisplayWidth() { +        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); +        mDisplayWidth = wm.getDefaultDisplay().getWidth(); +    } +      @Override      public boolean shouldDelayChildPressedState() {          return false; @@ -438,38 +449,19 @@ public class RelativeLayout extends ViewGroup {          final boolean isWrapContentWidth = widthMode != MeasureSpec.EXACTLY;          final boolean isWrapContentHeight = heightMode != MeasureSpec.EXACTLY; +        // We need to know our size for doing the correct computation of children positioning in RTL +        // mode but there is no practical way to get it instead of running the code below. +        // So, instead of running the code twice, we just set the width to the "display width" +        // before the computation and then, as a last pass, we will update their real position with +        // an offset equals to "displayWidth - width". +        final int layoutDirection = getLayoutDirection(); +        if (isLayoutRtl() && myWidth == -1) { +            myWidth = mDisplayWidth; +        } +          View[] views = mSortedHorizontalChildren;          int count = views.length; -        // We need to know our size for doing the correct computation of positioning in RTL mode -        if (isLayoutRtl() && (myWidth == -1 || isWrapContentWidth)) { -            int w = getPaddingStart() + getPaddingEnd(); -            for (int i = 0; i < count; i++) { -                View child = views[i]; -                if (child.getVisibility() != GONE) { -                    LayoutParams params = (LayoutParams) child.getLayoutParams(); -                    int[] rules = params.getRules(View.LAYOUT_DIRECTION_LTR); - -                    applyHorizontalSizeRules(params, myWidth, rules); -                    measureChildHorizontal(child, params, -1, myHeight); - -                    w += child.getMeasuredWidth(); -                    w += params.leftMargin + params.rightMargin; -                } -            } -            if (myWidth == -1) { -                // Easy case: "myWidth" was undefined before so use the width we have just computed -                myWidth = w; -            } else { -                // "myWidth" was defined before, so take the min of it and the computed width if it -                // is a non null one -                if (w > 0) { -                    myWidth = Math.min(myWidth, w); -                } -            } -        } - -        final int layoutDirection = getLayoutDirection();          for (int i = 0; i < count; i++) {              View child = views[i];              if (child.getVisibility() != GONE) { @@ -500,7 +492,11 @@ public class RelativeLayout extends ViewGroup {                  }                  if (isWrapContentWidth) { -                    width = Math.max(width, params.mRight); +                    if (isLayoutRtl()) { +                        width = Math.max(width, myWidth - params.mLeft); +                    } else { +                        width = Math.max(width, params.mRight); +                    }                  }                  if (isWrapContentHeight) { @@ -628,6 +624,19 @@ public class RelativeLayout extends ViewGroup {              }          } +        if (isLayoutRtl()) { +            final int offsetWidth = myWidth - width; +            for (int i = 0; i < count; i++) { +                View child = getChildAt(i); +                if (child.getVisibility() != GONE) { +                    LayoutParams params = (LayoutParams) child.getLayoutParams(); +                    params.mLeft -= offsetWidth; +                    params.mRight -= offsetWidth; +                } +            } + +        } +          setMeasuredDimension(width, height);      }  |