Знак препинания отображается в начале текста LTR в ОС RTL

Рассмотрим фрагмент:

<TextView
    android:layout_width="wrap_content"
    android:layout_width="wrap_content"
    android:text="Hello!"
    android:textDirection="locale"/>

Код приводит к отображению «!Hello» вместо ожидаемого «Hello!» когда язык ОС установлен на RTL. Это наблюдается только в том случае, если для textDirection установлено значение «locale», в противном случае текст отображается правильно.

Мне нужно установить TextDirection в качестве локали, чтобы текст был выровнен в текстовом представлении в соответствии с локалью ОС. Есть ли способ использовать textdirection в качестве локали, не испортив рендеринг текста или любое другое простое решение для достижения того же эффекта.

PS: я хочу применить это на глобальном уровне ко всем текстовым представлениям и, следовательно, не могу использовать textAlignment (как viewStart), так как это испортит свойство гравитации, установленное для представлений. (в частности, гравитация, установленная как центральная горизонталь, будет игнорироваться в пользу textalignment = viewStart)


person yash mittal    schedule 14.11.2018    source источник


Ответы (1)


В "locale" нет ничего особенного, такое же отображение происходит, когда вы используете "rtl" для textDirection поля, в котором текст LTR заканчивается на !. Или . или любой другой знак препинания без строгой направленности.

Что может быть сделано:

  1. заканчивайте эти тексты символом &lrm;:

    android:text="Hello!\u200e"
    
  2. выберите "ltr" textDirection для этих полей.
  3. во время выполнения определите тестовые поля, которые начинаются с последовательности LTR или содержат только последовательность LTR (эта логика может измениться по вашему выбору), и примените к этим полям правила 1 или 2 (см. выше).
  4. вместо этого используйте android:textAlignment="viewStart":

    <FrameLayout
      android:layoutDirection="rtl" ...>
    
    <TextView
      android:text="Hello!"
      android:textAlignment="viewStart"
      android:layout_width="80dp"
      android:padding="12dp"
      android:background="@android:color/black"
      android:textColor="@android:color/white"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
    />
    
person Alex Cohn    schedule 14.11.2018
comment
вариант 2 не годится, так как заставляет текст выравниваться по левому краю (я хочу, чтобы выравнивание текста исходило из локали). Кроме того, невозможно написать эту логику динамического разрешения для каждого текстового просмотра. - person yash mittal; 14.11.2018
comment
Могу ли я вообще избежать использования textDirection? Моим мотивом использования textDirection в качестве локали было выравнивание текста в соответствии с локалью ОС (текст LTR и RTL должен быть выровнен по правому краю в RTL). - person yash mittal; 15.11.2018
comment
Вы можете установить правильное выравнивание, не выбирая textDirection: попробуйте android:textAlignment="viewStart" для локали RTL. - person Alex Cohn; 15.11.2018
comment
как я упоминал в описании вопроса, некоторые элементы textview могут иметь гравитацию, установленную в центре.. для них текст LTR и RTL должен оставаться в центре. Указание textAlignment как viewStart переопределит это свойство гравитации и выровняет текст по viewStart. - person yash mittal; 15.11.2018
comment
Это не то, что я вижу. Может быть, это зависит от платформы, я не могу сказать. - person Alex Cohn; 15.11.2018