Skip to content

Commit a2daab7

Browse files
committed
ref: Text alignment improvements
1 parent 4e9ed9b commit a2daab7

File tree

9 files changed

+38
-122
lines changed

9 files changed

+38
-122
lines changed

apps/automated/src/ui/label/label-tests-native.android.ts

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,22 @@ import { AndroidHelper } from '@nativescript/core/ui/core/view';
55
const UNEXPECTED_VALUE = 'unexpected value';
66

77
export function getNativeTextAlignment(label: labelModule.Label): string {
8-
const alignment = label.android.getTextAlignment();
9-
10-
if (alignment === android.view.View.TEXT_ALIGNMENT_VIEW_START) {
11-
return 'initial';
12-
}
13-
14-
if (alignment === android.view.View.TEXT_ALIGNMENT_TEXT_START) {
15-
return CoreTypes.TextAlignment.left;
16-
}
17-
18-
if (alignment === android.view.View.TEXT_ALIGNMENT_CENTER) {
19-
return CoreTypes.TextAlignment.center;
20-
}
21-
22-
if (alignment === android.view.View.TEXT_ALIGNMENT_TEXT_END) {
23-
return CoreTypes.TextAlignment.right;
24-
}
25-
26-
label.android.setTextAlignment(android.view.View.TEXT_ALIGNMENT_TEXT_END);
27-
28-
return UNEXPECTED_VALUE;
29-
}
30-
31-
export function getNativeTextAlignmentWithoutRtlSupport(label: labelModule.Label): string {
328
let hGravity = label.android.getGravity() & android.view.Gravity.HORIZONTAL_GRAVITY_MASK;
9+
const alignment = label.android.getTextAlignment();
3310

34-
if (hGravity === android.view.Gravity.START) {
11+
if (hGravity === android.view.Gravity.START && alignment === android.view.View.TEXT_ALIGNMENT_VIEW_START) {
3512
return 'initial';
3613
}
3714

38-
if (hGravity === android.view.Gravity.LEFT) {
15+
if (hGravity === android.view.Gravity.LEFT && alignment === android.view.View.TEXT_ALIGNMENT_GRAVITY) {
3916
return CoreTypes.TextAlignment.left;
4017
}
4118

42-
if (hGravity === android.view.Gravity.CENTER_HORIZONTAL) {
19+
if (hGravity === android.view.Gravity.CENTER_HORIZONTAL && alignment === android.view.View.TEXT_ALIGNMENT_CENTER) {
4320
return CoreTypes.TextAlignment.center;
4421
}
4522

46-
if (hGravity === android.view.Gravity.RIGHT) {
23+
if (hGravity === android.view.Gravity.RIGHT && alignment === android.view.View.TEXT_ALIGNMENT_GRAVITY) {
4724
return CoreTypes.TextAlignment.right;
4825
}
4926

apps/automated/src/ui/label/label-tests-native.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ import * as labelModule from '@nativescript/core/ui/label';
33
import * as colorModule from '@nativescript/core/color';
44

55
export declare function getNativeTextAlignment(label: labelModule.Label): string;
6-
export declare function getNativeTextAlignmentWithoutRtlSupport(label: labelModule.Label): string;
76
export declare function getNativeBackgroundColor(label: labelModule.Label): colorModule.Color;

apps/automated/src/ui/label/label-tests.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -525,39 +525,6 @@ export class LabelTest extends testModule.UITest<LabelModule.Label> {
525525
TKUnit.assertEqual(view.style.backgroundColor.hex, '#FF0000');
526526
}
527527

528-
public testNativeTextAlignmentWithoutRtlSupportFromCss() {
529-
const view = this.testView;
530-
const page = this.testPage;
531-
const hasRtlSupportOrig = LabelModule.Label.hasRtlSupport();
532-
533-
this.waitUntilTestElementIsLoaded();
534-
535-
LabelModule.Label._hasRtlSupport = false;
536-
page.css = 'label { text-align: ' + this.expectedTextAlignment + '; }';
537-
538-
const actualResult = labelTestsNative.getNativeTextAlignmentWithoutRtlSupport(view);
539-
540-
LabelModule.Label._hasRtlSupport = hasRtlSupportOrig;
541-
542-
TKUnit.assert(actualResult, this.expectedTextAlignment);
543-
}
544-
545-
public testNativeTextAlignmentWithoutRtlSupportFromLocal() {
546-
const view = this.testView;
547-
const hasRtlSupportOrig = LabelModule.Label.hasRtlSupport();
548-
549-
this.waitUntilTestElementIsLoaded();
550-
551-
LabelModule.Label._hasRtlSupport = false;
552-
view.style.textAlignment = this.expectedTextAlignment;
553-
554-
const actualResult = labelTestsNative.getNativeTextAlignmentWithoutRtlSupport(view);
555-
556-
LabelModule.Label._hasRtlSupport = hasRtlSupportOrig;
557-
558-
TKUnit.assertEqual(actualResult, this.expectedTextAlignment);
559-
}
560-
561528
public testNativeTextAlignmentFromCss() {
562529
const view = this.testView;
563530
const page = this.testPage;

packages/core/ui/core/view/index.d.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,6 @@ export abstract class View extends ViewCommon {
152152
*/
153153
public static accessibilityFocusChangedEvent: string;
154154

155-
/**
156-
* @private
157-
*/
158-
public static _hasRtlSupport: boolean;
159-
160155
/**
161156
* Gets the android-specific native instance that lies behind this proxy. Will be available if running on an Android platform.
162157
*/
@@ -801,11 +796,6 @@ export abstract class View extends ViewCommon {
801796

802797
public static combineMeasuredStates(curState: number, newState): number;
803798

804-
/**
805-
* Check if RTL is supported by the app
806-
*/
807-
public static hasRtlSupport(): boolean;
808-
809799
/**
810800
* Tries to focus the view.
811801
* Returns a value indicating whether this view or one of its descendants actually took focus.

packages/core/ui/core/view/view-common.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
8787
public static accessibilityFocusChangedEvent = accessibilityFocusChangedEvent;
8888
public static accessibilityPerformEscapeEvent = accessibilityPerformEscapeEvent;
8989

90-
public static _hasRtlSupport: boolean;
91-
9290
public accessibilityIdentifier: string;
9391
public accessibilityLabel: string;
9492
public accessibilityValue: string;
@@ -1071,14 +1069,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
10711069
return ViewHelper.measureChild(parent, child, widthMeasureSpec, heightMeasureSpec);
10721070
}
10731071

1074-
public static hasRtlSupport(): boolean {
1075-
if (this._hasRtlSupport == null) {
1076-
this._hasRtlSupport = layout.hasRtlSupport();
1077-
}
1078-
1079-
return this._hasRtlSupport;
1080-
}
1081-
10821072
_setCurrentMeasureSpecs(widthMeasureSpec: number, heightMeasureSpec: number): boolean {
10831073
const changed: boolean = this._currentWidthMeasureSpec !== widthMeasureSpec || this._currentHeightMeasureSpec !== heightMeasureSpec;
10841074
this._currentWidthMeasureSpec = widthMeasureSpec;
Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { Label as LabelDefinition } from '.';
2-
import { textAlignmentProperty, TextBase, whiteSpaceProperty } from '../text-base';
2+
import { TextBase, whiteSpaceProperty } from '../text-base';
33
import { profile } from '../../profiling';
44
import { CSSType } from '../core/view';
55
import { booleanConverter } from '../core/view-base';
66
import { CoreTypes } from '../../core-types';
7-
import { SDK_VERSION } from '../../utils';
87

98
export * from '../text-base';
109

@@ -35,52 +34,15 @@ export class Label extends TextBase implements LabelDefinition {
3534
textView.setSingleLine(true);
3635
textView.setEllipsize(android.text.TextUtils.TruncateAt.END);
3736
textView.setGravity(android.view.Gravity.CENTER_VERTICAL);
38-
39-
if (Label.hasRtlSupport()) {
40-
// This is a default to match iOS layout direction behaviour
41-
textView.setTextAlignment(android.view.View.TEXT_ALIGNMENT_VIEW_START);
42-
}
4337
}
4438

4539
[whiteSpaceProperty.setNative](value: CoreTypes.WhiteSpaceType) {
4640
// Label initial value is no-wrap. set in initNativeView
4741
const newValue = value === 'initial' ? 'nowrap' : value;
4842
super[whiteSpaceProperty.setNative](newValue);
4943
}
50-
51-
[textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) {
52-
// TextAlignment API has no effect unless app has rtl support defined in manifest
53-
// so use gravity to align text as a fallback
54-
if (!Label.hasRtlSupport()) {
55-
super[textAlignmentProperty.setNative](value);
56-
} else {
57-
switch (value) {
58-
case 'left':
59-
case 'justify':
60-
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_TEXT_START);
61-
break;
62-
case 'center':
63-
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_CENTER);
64-
break;
65-
case 'right':
66-
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_TEXT_END);
67-
break;
68-
default:
69-
// initial
70-
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_VIEW_START);
71-
break;
72-
}
73-
74-
if (SDK_VERSION >= 26) {
75-
if (value === 'justify') {
76-
this.nativeTextViewProtected.setJustificationMode(android.text.Layout.JUSTIFICATION_MODE_INTER_WORD);
77-
} else {
78-
this.nativeTextViewProtected.setJustificationMode(android.text.Layout.JUSTIFICATION_MODE_NONE);
79-
}
80-
}
81-
}
82-
}
8344
}
8445

8546
Label.prototype._isSingleLine = true;
47+
Label.prototype._isManualRtlTextStyleNeeded = true;
8648
Label.prototype.recycleNativeView = 'auto';

packages/core/ui/text-base/index.android.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,20 @@ export class TextBase extends TextBaseCommon {
187187
public initNativeView(): void {
188188
super.initNativeView();
189189
initializeTextTransformation();
190+
190191
const nativeView = this.nativeTextViewProtected;
192+
191193
this._defaultTransformationMethod = nativeView.getTransformationMethod();
192194
this._defaultMovementMethod = nativeView.getMovementMethod();
193195
this._minHeight = nativeView.getMinHeight();
194196
this._maxHeight = nativeView.getMaxHeight();
195197
this._minLines = nativeView.getMinLines();
196198
this._maxLines = nativeView.getMaxLines();
199+
200+
if (layout.hasRtlSupport() && this._isManualRtlTextStyleNeeded) {
201+
// This is a default to match iOS layout direction behaviour
202+
nativeView.setTextAlignment(android.view.View.TEXT_ALIGNMENT_VIEW_START);
203+
}
197204
}
198205

199206
public disposeNativeView(): void {
@@ -305,21 +312,38 @@ export class TextBase extends TextBaseCommon {
305312
return 'initial';
306313
}
307314
[textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) {
315+
// TextAlignment API has no effect unless app has rtl support defined in manifest
316+
const supportsRtlTextAlign = layout.hasRtlSupport() && this._isManualRtlTextStyleNeeded;
308317
const verticalGravity = this.nativeTextViewProtected.getGravity() & android.view.Gravity.VERTICAL_GRAVITY_MASK;
309318

319+
// In the cases of left and right, use gravity alignment as TEXT_ALIGNMENT_TEXT_START
320+
// and TEXT_ALIGNMENT_TEXT_END are affected by text direction
321+
// Also, gravity start seem to affect text direction based on language, so use gravity left and right respectively
310322
switch (value) {
311323
case 'left':
312324
case 'justify':
325+
if (supportsRtlTextAlign) {
326+
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_GRAVITY);
327+
}
313328
this.nativeTextViewProtected.setGravity(android.view.Gravity.LEFT | verticalGravity);
314329
break;
315330
case 'center':
331+
if (supportsRtlTextAlign) {
332+
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_CENTER);
333+
}
316334
this.nativeTextViewProtected.setGravity(android.view.Gravity.CENTER_HORIZONTAL | verticalGravity);
317335
break;
318336
case 'right':
337+
if (supportsRtlTextAlign) {
338+
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_GRAVITY);
339+
}
319340
this.nativeTextViewProtected.setGravity(android.view.Gravity.RIGHT | verticalGravity);
320341
break;
321342
default:
322343
// initial
344+
if (supportsRtlTextAlign) {
345+
this.nativeTextViewProtected.setTextAlignment(android.view.View.TEXT_ALIGNMENT_VIEW_START);
346+
}
323347
this.nativeTextViewProtected.setGravity(android.view.Gravity.START | verticalGravity);
324348
break;
325349
}

packages/core/ui/text-base/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ export class TextBase extends View implements AddChildFromBuilder {
181181
* @private
182182
*/
183183
_isSingleLine: boolean;
184+
185+
/**
186+
* @private
187+
*/
188+
_isManualRtlTextStyleNeeded: boolean;
184189
//@endprivate
185190
}
186191

packages/core/ui/text-base/text-base-common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
2323
public static iosTextAnimationFallback = true;
2424

2525
public _isSingleLine: boolean;
26+
public _isManualRtlTextStyleNeeded: boolean;
2627
public text: string;
2728
public formattedText: FormattedString;
2829
public iosTextAnimation: 'inherit' | boolean;
@@ -223,6 +224,7 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
223224
}
224225

225226
TextBaseCommon.prototype._isSingleLine = false;
227+
TextBaseCommon.prototype._isManualRtlTextStyleNeeded = false;
226228

227229
export const textProperty = new Property<TextBaseCommon, string>({
228230
name: 'text',

0 commit comments

Comments
 (0)