Изменение направления текста в TextView при использовании текста LTR в середине строки RTL

Наше приложение поддерживает разные местные жители. В середине есть строка с двумя заменяемыми значениями (деньги с символом валюты, USD$XXXXX ). Но когда язык арабский, поведение странное. Направление текста меняется, если текст состоит более чем из одной строки. И только тексты в первой строке правильные, а форматирование в других строках чем-то перекрывается!

Как вы можете видеть на скриншоте, зеленые линии правильные, как и ожидалось, а красные — неправильные.

введите описание изображения здесь

До сих пор я пытался использовать:

  • BidFormatter
  • Юникод

Проблема в том, что после использования двунаправленного формата первое число правильное, а второе нет.

И после использования BidiFormat и unicode все числа в порядке, но когда текст длинный и состоит из нескольких строк, только первая строка верна, а другие строки снова неверны.

Что касается Unicode, я просмотрел: Стандартное приложение Unicode® № 9 ДВУНАПРАВЛЕННЫЙ АЛГОРИТМ UNICODE (вы можете напрямую см. эту часть, если вас интересует только основное содержание)

Вы можете ознакомиться с этим репозиторием: Github Link

Вот код, который я использовал для быстрого ознакомления:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    setTextViewTexts(R.id.tvLtrOneLine, formatWithCurrency(), R.string.text_short_english)
    setTextViewTexts(R.id.tvLtrTwoLines, formatWithCurrency(), R.string.text_long_english)
    setTextViewTexts(R.id.tvRtlOneLine, formatWithCurrency(), R.string.text_short_arabic)
    setTextViewTexts(R.id.tvRtlOneLineBidi, bidiFormatter(formatWithCurrency()), R.string.text_short_arabic)
    setTextViewTexts(R.id.tvRtlOneLineRtlFormatter, rtlMaker(formatWithCurrency()), R.string.text_short_arabic)
    setTextViewTexts(R.id.tvRtlTwoLines, formatWithCurrency(), R.string.text_long_arabic)
    setTextViewTexts(R.id.tvRtlTwoLinesBidi, bidiFormatter(formatWithCurrency()), R.string.text_long_arabic)
    setTextViewTexts(R.id.tvRtlTwoLinesRtlFormatter, rtlMaker(formatWithCurrency()), R.string.text_long_arabic)
}

private fun setTextViewTexts(textViewId: Int, text: String, stringResource: Int) {
    findViewById<TextView>(textViewId).text = getString(stringResource, text, text)
}

private fun formatWithCurrency(): String {
    val currency = "USD$"
    val price = 200
    val priceBuilder = StringBuilder("")
    priceBuilder.append(currency)
    priceBuilder.append(getDecimalFormattedPrice(price))
    return priceBuilder.toString()
}

private fun getDecimalFormattedPrice(price: Int): String {
    return DecimalFormat("0.00").format(price)
}

private fun rtlMaker(text: String): String {
    return "\u2066" + bidiFormatter(text) + "\u2069"
}

private fun bidiFormatter(text: String): String {
    return BidiFormatter.getInstance().unicodeWrap(text)
}

Это баг андроида или есть обходной путь?

Чтобы увидеть ошибку, загрузите репозиторий, запустите его на любом устройстве и измените язык устройства на арабский (Египет).

РЕДАКТИРОВАТЬ: я отправляю отчет об ошибке


person Omid Heshmatinia    schedule 05.12.2019    source источник


Ответы (1)


@Omid Heshmatinia, вы можете использовать spannableString или Html.fromHtml(string), это даст вам более точный результат :)

person hio    schedule 14.12.2019
comment
Я пробовал оба из них, и ни один из них не работает в этом случае - person Omid Heshmatinia; 16.12.2019