diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2012-03-13 19:37:57 -0700 |
---|---|---|
committer | Fabrice Di Meglio <fdimeglio@google.com> | 2012-04-04 12:20:45 -0700 |
commit | 9da0f8a5c4bccf8e722ae2ebf43873457aec3271 (patch) | |
tree | 62b3bf712216de07ea78bd00b436e7a480a0b754 | |
parent | 6756f74d81808ef9fc0cdab3c8848723122587c1 (diff) | |
download | frameworks_base-9da0f8a5c4bccf8e722ae2ebf43873457aec3271.zip frameworks_base-9da0f8a5c4bccf8e722ae2ebf43873457aec3271.tar.gz frameworks_base-9da0f8a5c4bccf8e722ae2ebf43873457aec3271.tar.bz2 |
Add View textAlignment
- fix bug #6163772
- use bits field and pack them as much as possible
- take care of "supportsRtl" flag from Manifest
- add visual unit tests
CTS unit tests in another CL
Change-Id: Ib77c4eb423854209af130688c5ef9977401a9c1c
-rw-r--r-- | api/current.txt | 28 | ||||
-rw-r--r-- | core/java/android/view/View.java | 330 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 12 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 57 | ||||
-rwxr-xr-x | core/res/res/values/attrs.xml | 24 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 1 | ||||
-rw-r--r-- | tests/BiDiTests/res/layout/textview_alignment_ltr.xml | 578 | ||||
-rw-r--r-- | tests/BiDiTests/res/layout/textview_alignment_rtl.xml | 578 | ||||
-rw-r--r-- | tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java | 18 | ||||
-rw-r--r-- | tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java | 31 | ||||
-rw-r--r-- | tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java | 31 |
11 files changed, 1658 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt index 95007b5..b98e41c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -596,7 +596,7 @@ package android { field public static final int layerType = 16843604; // 0x1010354 field public static final int layout = 16842994; // 0x10100f2 field public static final int layoutAnimation = 16842988; // 0x10100ec - field public static final int layoutDirection = 16843690; // 0x10103aa + field public static final int layoutDirection = 16843691; // 0x10103ab field public static final int layout_above = 16843140; // 0x1010184 field public static final int layout_alignBaseline = 16843142; // 0x1010186 field public static final int layout_alignBottom = 16843146; // 0x101018a @@ -618,10 +618,10 @@ package android { field public static final int layout_height = 16842997; // 0x10100f5 field public static final int layout_margin = 16842998; // 0x10100f6 field public static final int layout_marginBottom = 16843002; // 0x10100fa - field public static final int layout_marginEnd = 16843694; // 0x10103ae + field public static final int layout_marginEnd = 16843695; // 0x10103af field public static final int layout_marginLeft = 16842999; // 0x10100f7 field public static final int layout_marginRight = 16843001; // 0x10100f9 - field public static final int layout_marginStart = 16843693; // 0x10103ad + field public static final int layout_marginStart = 16843694; // 0x10103ae field public static final int layout_marginTop = 16843000; // 0x10100f8 field public static final int layout_row = 16843643; // 0x101037b field public static final int layout_rowSpan = 16843644; // 0x101037c @@ -717,10 +717,10 @@ package android { field public static final int packageNames = 16843649; // 0x1010381 field public static final int padding = 16842965; // 0x10100d5 field public static final int paddingBottom = 16842969; // 0x10100d9 - field public static final int paddingEnd = 16843692; // 0x10103ac + field public static final int paddingEnd = 16843693; // 0x10103ad field public static final int paddingLeft = 16842966; // 0x10100d6 field public static final int paddingRight = 16842968; // 0x10100d8 - field public static final int paddingStart = 16843691; // 0x10103ab + field public static final int paddingStart = 16843692; // 0x10103ac field public static final int paddingTop = 16842967; // 0x10100d7 field public static final int panelBackground = 16842846; // 0x101005e field public static final int panelColorBackground = 16842849; // 0x1010061 @@ -962,6 +962,7 @@ package android { field public static final int tension = 16843370; // 0x101026a field public static final int testOnly = 16843378; // 0x1010272 field public static final int text = 16843087; // 0x101014f + field public static final int textAlignment = 16843690; // 0x10103aa field public static final int textAllCaps = 16843660; // 0x101038c field public static final int textAppearance = 16842804; // 0x1010034 field public static final int textAppearanceButton = 16843271; // 0x1010207 @@ -23209,6 +23210,7 @@ package android.view { method public void buildLayer(); method public boolean callOnClick(); method public boolean canResolveLayoutDirection(); + method public boolean canResolveTextAlignment(); method public boolean canResolveTextDirection(); method public boolean canScrollHorizontally(int); method public boolean canScrollVertically(int); @@ -23329,6 +23331,7 @@ package android.view { method public float getPivotY(); method public int getResolvedLayoutDirection(); method public int getResolvedLayoutDirection(android.graphics.drawable.Drawable); + method public int getResolvedTextAlignment(); method public int getResolvedTextDirection(); method public android.content.res.Resources getResources(); method public final int getRight(); @@ -23349,6 +23352,7 @@ package android.view { method public int getSystemUiVisibility(); method public java.lang.Object getTag(); method public java.lang.Object getTag(int); + method public int getTextAlignment(); method public int getTextDirection(); method public final int getTop(); method protected float getTopFadingEdgeStrength(); @@ -23456,6 +23460,8 @@ package android.view { method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); method public void onResolvedLayoutDirectionChanged(); method public void onResolvedLayoutDirectionReset(); + method public void onResolvedTextAlignmentChanged(); + method public void onResolvedTextAlignmentReset(); method public void onResolvedTextDirectionChanged(); method public void onResolvedTextDirectionReset(); method protected void onRestoreInstanceState(android.os.Parcelable); @@ -23496,11 +23502,13 @@ package android.view { method public boolean requestRectangleOnScreen(android.graphics.Rect); method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean); method public void resetResolvedLayoutDirection(); + method public void resetResolvedTextAlignment(); method public void resetResolvedTextDirection(); method public void resolveLayoutDirection(); method public void resolvePadding(); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); + method public void resolveTextAlignment(); method public void resolveTextDirection(); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); @@ -23584,6 +23592,7 @@ package android.view { method public void setSystemUiVisibility(int); method public void setTag(java.lang.Object); method public void setTag(int, java.lang.Object); + method public void setTextAlignment(int); method public void setTextDirection(int); method public final void setTop(int); method public void setTouchDelegate(android.view.TouchDelegate); @@ -23694,6 +23703,15 @@ package android.view { field public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1; // 0x1 field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0 field public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536; // 0x600 + field public static final int TEXT_ALIGNMENT_CENTER = 4; // 0x4 + field protected static int TEXT_ALIGNMENT_DEFAULT; + field public static final int TEXT_ALIGNMENT_GRAVITY = 1; // 0x1 + field public static final int TEXT_ALIGNMENT_INHERIT = 0; // 0x0 + field public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = 131072; // 0x20000 + field public static final int TEXT_ALIGNMENT_TEXT_END = 3; // 0x3 + field public static final int TEXT_ALIGNMENT_TEXT_START = 2; // 0x2 + field public static final int TEXT_ALIGNMENT_VIEW_END = 6; // 0x6 + field public static final int TEXT_ALIGNMENT_VIEW_START = 5; // 0x5 field public static final int TEXT_DIRECTION_ANY_RTL = 2; // 0x2 field protected static int TEXT_DIRECTION_DEFAULT; field public static final int TEXT_DIRECTION_FIRST_STRONG = 1; // 0x1 diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c40a7d5..afd07df 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -624,6 +624,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack * @attr ref android.R.styleable#View_soundEffectsEnabled * @attr ref android.R.styleable#View_tag + * @attr ref android.R.styleable#View_textAlignment * @attr ref android.R.styleable#View_transformPivotX * @attr ref android.R.styleable#View_transformPivotY * @attr ref android.R.styleable#View_translationX @@ -1827,15 +1828,15 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal public static final int TEXT_DIRECTION_LOCALE = 5; /** - * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED) - * @hide + * Default text direction is inherited */ - static final int TEXT_DIRECTION_MASK_SHIFT = 6; + protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT; /** - * Default text direction is inherited + * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED) + * @hide */ - protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT; + static final int TEXT_DIRECTION_MASK_SHIFT = 6; /** * Mask for use with private flags indicating bits used for text direction. @@ -1882,6 +1883,113 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_RESOLVED_MASK_SHIFT; + /* + * Default text alignment. The text alignment of this View is inherited from its parent. + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_INHERIT = 0; + + /** + * Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL, + * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_GRAVITY = 1; + + /** + * Align to the start of the paragraph, e.g. ALIGN_NORMAL. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_TEXT_START = 2; + + /** + * Align to the end of the paragraph, e.g. ALIGN_OPPOSITE. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_TEXT_END = 3; + + /** + * Center the paragraph, e.g. ALIGN_CENTER. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_CENTER = 4; + + /** + * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved + * layoutDirection is LTR, and ALIGN_RIGHT otherwise. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_VIEW_START = 5; + + /** + * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved + * layoutDirection is LTR, and ALIGN_LEFT otherwise. + * + * Use with {@link #setTextAlignment(int)} + */ + public static final int TEXT_ALIGNMENT_VIEW_END = 6; + + /** + * Default text alignment is inherited + */ + protected static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY; + + /** + * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED) + * @hide + */ + static final int TEXT_ALIGNMENT_MASK_SHIFT = 13; + + /** + * Mask for use with private flags indicating bits used for text alignment. + * @hide + */ + static final int TEXT_ALIGNMENT_MASK = 0x00000007 << TEXT_ALIGNMENT_MASK_SHIFT; + + /** + * Array of text direction flags for mapping attribute "textAlignment" to correct + * flag value. + * @hide + */ + private static final int[] TEXT_ALIGNMENT_FLAGS = { + TEXT_ALIGNMENT_INHERIT << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_TEXT_START << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_TEXT_END << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_CENTER << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_VIEW_START << TEXT_ALIGNMENT_MASK_SHIFT, + TEXT_ALIGNMENT_VIEW_END << TEXT_ALIGNMENT_MASK_SHIFT + }; + + /** + * Indicates whether the view text alignment has been resolved. + * @hide + */ + static final int TEXT_ALIGNMENT_RESOLVED = 0x00000008 << TEXT_ALIGNMENT_MASK_SHIFT; + + /** + * Bit shift to get the resolved text alignment. + * @hide + */ + static final int TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17; + + /** + * Mask for use with private flags indicating bits used for text alignment. + * @hide + */ + static final int TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007 << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + + /** + * Indicates whether if the view text alignment has been resolved to gravity + */ + public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = + TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + /* End of masks for mPrivateFlags2 */ @@ -2841,7 +2949,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED; // Set layout and text direction defaults mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) | - (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT); + (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT) | + (TEXT_ALIGNMENT_DEFAULT << TEXT_ALIGNMENT_MASK_SHIFT); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS); mUserPaddingStart = -1; @@ -3222,6 +3331,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mPrivateFlags2 |= TEXT_DIRECTION_FLAGS[textDirection]; } break; + case R.styleable.View_textAlignment: + // Clear any text alignment flag already set + mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK; + // Set the text alignment flag depending on the value of the attribute + final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT); + mPrivateFlags2 |= TEXT_ALIGNMENT_FLAGS[textAlignment]; + break; } } @@ -9989,6 +10105,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal resolveLayoutDirection(); resolvePadding(); resolveTextDirection(); + resolveTextAlignment(); if (isFocused()) { InputMethodManager imm = InputMethodManager.peekInstance(); imm.focusIn(this); @@ -10218,6 +10335,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mCurrentAnimation = null; resetResolvedLayoutDirection(); + resetResolvedTextAlignment(); } /** @@ -14766,7 +14884,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * {@link #TEXT_DIRECTION_ANY_RTL}, * {@link #TEXT_DIRECTION_LTR}, * {@link #TEXT_DIRECTION_RTL}, - * {@link #TEXT_DIRECTION_LOCALE}, + * {@link #TEXT_DIRECTION_LOCALE} */ @ViewDebug.ExportedProperty(category = "text", mapping = { @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"), @@ -14790,7 +14908,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * {@link #TEXT_DIRECTION_ANY_RTL}, * {@link #TEXT_DIRECTION_LTR}, * {@link #TEXT_DIRECTION_RTL}, - * {@link #TEXT_DIRECTION_LOCALE}, + * {@link #TEXT_DIRECTION_LOCALE} */ public void setTextDirection(int textDirection) { if (getTextDirection() != textDirection) { @@ -14799,6 +14917,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal resetResolvedTextDirection(); // Set the new text direction mPrivateFlags2 |= ((textDirection << TEXT_DIRECTION_MASK_SHIFT) & TEXT_DIRECTION_MASK); + // Refresh requestLayout(); invalidate(true); } @@ -14818,7 +14937,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * {@link #TEXT_DIRECTION_ANY_RTL}, * {@link #TEXT_DIRECTION_LTR}, * {@link #TEXT_DIRECTION_RTL}, - * {@link #TEXT_DIRECTION_LOCALE}, + * {@link #TEXT_DIRECTION_LOCALE} */ public int getResolvedTextDirection() { // The text direction will be resolved only if needed @@ -14927,6 +15046,199 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal public void onResolvedTextDirectionReset() { } + /** + * Return the value specifying the text alignment or policy that was set with + * {@link #setTextAlignment(int)}. + * + * @return the defined text alignment. It can be one of: + * + * {@link #TEXT_ALIGNMENT_INHERIT}, + * {@link #TEXT_ALIGNMENT_GRAVITY}, + * {@link #TEXT_ALIGNMENT_CENTER}, + * {@link #TEXT_ALIGNMENT_TEXT_START}, + * {@link #TEXT_ALIGNMENT_TEXT_END}, + * {@link #TEXT_ALIGNMENT_VIEW_START}, + * {@link #TEXT_ALIGNMENT_VIEW_END} + */ + @ViewDebug.ExportedProperty(category = "text", mapping = { + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") + }) + public int getTextAlignment() { + return (mPrivateFlags2 & TEXT_ALIGNMENT_MASK) >> TEXT_ALIGNMENT_MASK_SHIFT; + } + + /** + * Set the text alignment. + * + * @param textAlignment The text alignment to set. Should be one of + * + * {@link #TEXT_ALIGNMENT_INHERIT}, + * {@link #TEXT_ALIGNMENT_GRAVITY}, + * {@link #TEXT_ALIGNMENT_CENTER}, + * {@link #TEXT_ALIGNMENT_TEXT_START}, + * {@link #TEXT_ALIGNMENT_TEXT_END}, + * {@link #TEXT_ALIGNMENT_VIEW_START}, + * {@link #TEXT_ALIGNMENT_VIEW_END} + * + * @attr ref android.R.styleable#View_textAlignment + */ + public void setTextAlignment(int textAlignment) { + if (textAlignment != getTextAlignment()) { + // Reset the current and resolved text alignment + mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK; + resetResolvedTextAlignment(); + // Set the new text alignment + mPrivateFlags2 |= ((textAlignment << TEXT_ALIGNMENT_MASK_SHIFT) & TEXT_ALIGNMENT_MASK); + // Refresh + requestLayout(); + invalidate(true); + } + } + + /** + * Return the resolved text alignment. + * + * The resolved text alignment. This needs resolution if the value is + * TEXT_ALIGNMENT_INHERIT. The resolution matches {@link #setTextAlignment(int)} if it is + * not TEXT_ALIGNMENT_INHERIT, otherwise resolution proceeds up the parent chain of the view. + * + * @return the resolved text alignment. Returns one of: + * + * {@link #TEXT_ALIGNMENT_GRAVITY}, + * {@link #TEXT_ALIGNMENT_CENTER}, + * {@link #TEXT_ALIGNMENT_TEXT_START}, + * {@link #TEXT_ALIGNMENT_TEXT_END}, + * {@link #TEXT_ALIGNMENT_VIEW_START}, + * {@link #TEXT_ALIGNMENT_VIEW_END} + */ + @ViewDebug.ExportedProperty(category = "text", mapping = { + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"), + @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END") + }) + public int getResolvedTextAlignment() { + // If text alignment is not resolved, then resolve it + if ((mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED) != TEXT_ALIGNMENT_RESOLVED) { + resolveTextAlignment(); + } + return (mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED_MASK) >> TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT; + } + + /** + * Resolve the text alignment. Will call {@link View#onResolvedTextAlignmentChanged} when + * resolution is done. + */ + public void resolveTextAlignment() { + // Reset any previous text alignment resolution + mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK); + + if (hasRtlSupport()) { + // Set resolved text alignment flag depending on text alignment flag + final int textAlignment = getTextAlignment(); + switch (textAlignment) { + case TEXT_ALIGNMENT_INHERIT: + // Check if we can resolve the text alignment + if (canResolveLayoutDirection() && mParent instanceof View) { + View view = (View) mParent; + + final int parentResolvedTextAlignment = view.getResolvedTextAlignment(); + switch (parentResolvedTextAlignment) { + case TEXT_ALIGNMENT_GRAVITY: + case TEXT_ALIGNMENT_TEXT_START: + case TEXT_ALIGNMENT_TEXT_END: + case TEXT_ALIGNMENT_CENTER: + case TEXT_ALIGNMENT_VIEW_START: + case TEXT_ALIGNMENT_VIEW_END: + // Resolved text alignment is the same as the parent resolved + // text alignment + mPrivateFlags2 |= + (parentResolvedTextAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); + break; + default: + // Use default resolved text alignment + mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + } + } + else { + // We cannot do the resolution if there is no parent so use the default + mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + } + break; + case TEXT_ALIGNMENT_GRAVITY: + case TEXT_ALIGNMENT_TEXT_START: + case TEXT_ALIGNMENT_TEXT_END: + case TEXT_ALIGNMENT_CENTER: + case TEXT_ALIGNMENT_VIEW_START: + case TEXT_ALIGNMENT_VIEW_END: + // Resolved text alignment is the same as text alignment + mPrivateFlags2 |= (textAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT); + break; + default: + // Use default resolved text alignment + mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + } + } else { + // Use default resolved text alignment + mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT; + } + + // Set the resolved + mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED; + onResolvedTextAlignmentChanged(); + } + + /** + * Check if text alignment resolution can be done. + * + * @return true if text alignment resolution can be done otherwise return false. + */ + public boolean canResolveTextAlignment() { + switch (getTextAlignment()) { + case TEXT_DIRECTION_INHERIT: + return (mParent != null); + default: + return true; + } + } + + /** + * Called when text alignment has been resolved. Subclasses that care about text alignment + * resolution should override this method. + * + * The default implementation does nothing. + */ + public void onResolvedTextAlignmentChanged() { + } + + /** + * Reset resolved text alignment. Text alignment can be resolved with a call to + * getResolvedTextAlignment(). Will call {@link View#onResolvedTextAlignmentReset} when + * reset is done. + */ + public void resetResolvedTextAlignment() { + // Reset any previous text alignment resolution + mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK); + onResolvedTextAlignmentReset(); + } + + /** + * Called when text alignment is reset. Subclasses that care about text alignment reset should + * override this method and do a reset of the text alignment of their children. The default + * implementation does nothing. + */ + public void onResolvedTextAlignmentReset() { + } + // // Properties // diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index d5c783f..ae5debe 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5056,6 +5056,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + @Override + public void onResolvedTextAlignmentReset() { + // Take care of resetting the children resolution too + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getTextAlignment() == TEXT_ALIGNMENT_INHERIT) { + child.resetResolvedTextAlignment(); + } + } + } + /** * Return true if the pressed state should be delayed for children or descendants of this * ViewGroup. Generally, this should be done for containers that can scroll, such as a List. diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index d2a1755..9867e47 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5340,24 +5340,63 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener physicalWidth, false); } + @Override + public void onResolvedLayoutDirectionReset() { + if (mLayoutAlignment != null) { + int resolvedTextAlignment = getResolvedTextAlignment(); + if (resolvedTextAlignment == TEXT_ALIGNMENT_VIEW_START || + resolvedTextAlignment == TEXT_ALIGNMENT_VIEW_END) { + mLayoutAlignment = null; + } + } + } + private Layout.Alignment getLayoutAlignment() { if (mLayoutAlignment == null) { - switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) { - case Gravity.START: + int textAlign = getResolvedTextAlignment(); + switch (textAlign) { + case TEXT_ALIGNMENT_GRAVITY: + switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) { + case Gravity.START: + mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL; + break; + case Gravity.END: + mLayoutAlignment = Layout.Alignment.ALIGN_OPPOSITE; + break; + case Gravity.LEFT: + mLayoutAlignment = Layout.Alignment.ALIGN_LEFT; + break; + case Gravity.RIGHT: + mLayoutAlignment = Layout.Alignment.ALIGN_RIGHT; + break; + case Gravity.CENTER_HORIZONTAL: + mLayoutAlignment = Layout.Alignment.ALIGN_CENTER; + break; + default: + mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL; + break; + } + break; + case TEXT_ALIGNMENT_TEXT_START: mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL; break; - case Gravity.END: + case TEXT_ALIGNMENT_TEXT_END: mLayoutAlignment = Layout.Alignment.ALIGN_OPPOSITE; break; - case Gravity.LEFT: - mLayoutAlignment = Layout.Alignment.ALIGN_LEFT; + case TEXT_ALIGNMENT_CENTER: + mLayoutAlignment = Layout.Alignment.ALIGN_CENTER; break; - case Gravity.RIGHT: - mLayoutAlignment = Layout.Alignment.ALIGN_RIGHT; + case TEXT_ALIGNMENT_VIEW_START: + mLayoutAlignment = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? + Layout.Alignment.ALIGN_RIGHT : Layout.Alignment.ALIGN_LEFT; break; - case Gravity.CENTER_HORIZONTAL: - mLayoutAlignment = Layout.Alignment.ALIGN_CENTER; + case TEXT_ALIGNMENT_VIEW_END: + mLayoutAlignment = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ? + Layout.Alignment.ALIGN_LEFT : Layout.Alignment.ALIGN_RIGHT; break; + case TEXT_ALIGNMENT_INHERIT: + // This should never happen as we have already resolved the text alignment + // but better safe than sorry so we just fall through default: mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL; break; diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 438c141..2b27585 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2079,6 +2079,7 @@ <!-- Locale --> <enum name="locale" value="3" /> </attr> + <!-- Direction of the text. A heuristic is used to determine the resolved text direction of paragraphs. --> <attr name="textDirection" format="integer"> @@ -2099,6 +2100,29 @@ <!-- The paragraph direction is coming from the system Locale. --> <enum name="locale" value="5" /> </attr> + + <!-- Alignment of the text. A heuristic is used to determine the resolved + text alignment. --> + <attr name="textAlignment" format="integer"> + <!-- Default --> + <enum name="inherit" value="0" /> + <!-- Default for the root view. The gravity determines the alignment, ALIGN_NORMAL, + ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s + text direction --> + <enum name="gravity" value="1" /> + <!-- Align to the start of the paragraph, e.g. ALIGN_NORMAL. --> + <enum name="textStart" value="2" /> + <!-- Align to the end of the paragraph, e.g. ALIGN_OPPOSITE. --> + <enum name="textEnd" value="3" /> + <!-- Center the paragraph, e.g. ALIGN_CENTER. --> + <enum name="center" value="4" /> + <!-- Align to the start of the view, which is ALIGN_LEFT if the view’s resolved + layoutDirection is LTR, and ALIGN_RIGHT otherwise. --> + <enum name="viewStart" value="5" /> + <!-- Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved + layoutDirection is LTR, and ALIGN_LEFT otherwise --> + <enum name="viewEnd" value="6" /> + </attr> </declare-styleable> <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e5f049d..7341c6c 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3554,6 +3554,7 @@ <public type="attr" name="supportsRtl" id="0x010103a8" /> <public type="attr" name="textDirection"/> + <public type="attr" name="textAlignment"/> <public type="attr" name="layoutDirection" /> diff --git a/tests/BiDiTests/res/layout/textview_alignment_ltr.xml b/tests/BiDiTests/res/layout/textview_alignment_ltr.xml new file mode 100644 index 0000000..0e1adba --- /dev/null +++ b/tests/BiDiTests/res/layout/textview_alignment_ltr.xml @@ -0,0 +1,578 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/textview_alignment_ltr" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="ltr"> + + <TableLayout android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <TableRow> + <TextView android:text="(unspecified)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity right" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity end" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="gravity" + android:gravity="center_horizontal"> + + <TextView android:text="inherit gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="center"> + + <TextView android:text="inherit gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textStart"> + + <TextView android:text="inherit textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textEnd"> + + <TextView android:text="inherit textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewStart"> + + <TextView android:text="inherit viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewEnd"> + + <TextView android:text="inherit viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + </TableLayout> + +</FrameLayout> diff --git a/tests/BiDiTests/res/layout/textview_alignment_rtl.xml b/tests/BiDiTests/res/layout/textview_alignment_rtl.xml new file mode 100644 index 0000000..12a90d5 --- /dev/null +++ b/tests/BiDiTests/res/layout/textview_alignment_rtl.xml @@ -0,0 +1,578 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/textview_alignment_rtl" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="rtl"> + + <TableLayout android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <TableRow> + <TextView android:text="(unspecified)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity right" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity end" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="gravity" + android:gravity="center_horizontal"> + + <TextView android:text="inherit gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="center"> + + <TextView android:text="inherit gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textStart"> + + <TextView android:text="inherit textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textEnd"> + + <TextView android:text="inherit textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewStart"> + + <TextView android:text="inherit viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewEnd"> + + <TextView android:text="inherit viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + </TableLayout> + +</FrameLayout> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index c5a1235..209597e 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -104,6 +104,16 @@ public class BiDiTestActivity extends Activity { addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas); addItem(result, "Canvas2", BiDiTestCanvas2.class, R.id.canvas2); + addItem(result, "TextView LTR", BiDiTestTextViewLtr.class, R.id.textview_ltr); + addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl); + addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale); + + addItem(result, "TextDirection LTR", BiDiTestTextViewDirectionLtr.class, R.id.textview_direction_ltr); + addItem(result, "TextDirection RTL", BiDiTestTextViewDirectionRtl.class, R.id.textview_direction_rtl); + + addItem(result, "TextAlignment LTR", BiDiTestTextViewAlignmentLtr.class, R.id.textview_alignment_ltr); + addItem(result, "TextAlignment RTL", BiDiTestTextViewAlignmentRtl.class, R.id.textview_alignment_rtl); + addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr); addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl); addItem(result, "Linear LOC", BiDiTestLinearLayoutLocale.class, R.id.linear_layout_locale); @@ -134,15 +144,9 @@ public class BiDiTestActivity extends Activity { addItem(result, "Margin MIXED", BiDiTestViewGroupMarginMixed.class, R.id.view_group_margin_mixed); - addItem(result, "TextView LTR", BiDiTestTextViewLtr.class, R.id.textview_ltr); - addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl); - addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale); - - addItem(result, "TextDirection LTR", BiDiTestTextViewDirectionLtr.class, R.id.textview_direction_ltr); - addItem(result, "TextDirection RTL", BiDiTestTextViewDirectionRtl.class, R.id.textview_direction_rtl); - addItem(result, "TextView Drawables LTR", BiDiTestTextViewDrawablesLtr.class, R.id.textview_drawables_ltr); addItem(result, "TextView Drawables RTL", BiDiTestTextViewDrawablesRtl.class, R.id.textview_drawables_rtl); + addItem(result, "Gallery LTR", BiDiTestGalleryLtr.class, R.id.gallery_ltr); addItem(result, "Gallery RTL", BiDiTestGalleryRtl.class, R.id.gallery_rtl); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java new file mode 100644 index 0000000..5ea5d81 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 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 com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestTextViewAlignmentLtr extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.textview_alignment_ltr, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java new file mode 100644 index 0000000..fcc7a5d --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 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 com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestTextViewAlignmentRtl extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.textview_alignment_rtl, container, false); + } +} |