Our app supports different locals. There's a string with two replaceable values (money with currency symbol, USD$XXXXX ) in middle of that. But, when the locale is Arabic, there is strange behaviour. The direction of text changes when the text is more than one line. And only the texts on the first line is correct, while formatting on other lines get overridden by something!
As you can see in the screenshot, the green lines are correct as expected and the red ones are the wrong ones.
So far I have tried using:
The problem is that, after using the bidi format, the first number is correct but the second number is not.
And after using BidiFormat and unicode all the numbers are fine but, when the text is long and becomes multiple lines, only first line is correct and other lines are wrong again.
For unicode, I looked at : Unicode® Standard Annex #9 UNICODE BIDIRECTIONAL ALGORITHM (you can directly see this part if you are only interested in the main content)
You can take a look into this repo : Github Link
Here is the code I used for quick reference:
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)
}
Is it an android bug or there is a workaround for that?
To see the bug, download the repository and run it on any device and change the device language to Arabic(Egypt)
EDIT: I submit the bug report
@Omid Heshmatinia you can use
spannableString
or
Html.fromHtml(string)
it's give you more accurate output :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With