Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How formatted string and then change style by annotations

i have 3 strings localizations

<string name="tests" formatted="true">Test<annotation font="bold"> testBold %1$s</annotation> end</string>
<string name="tests" formatted="true">Тест<annotation font="bold"> тестБолд %1$s</annotation> конец</string>
<string name="tests" formatted="true">Тест<annotation font="bold"> тестБолд %1$s</annotation> кінець</string>

How i can add some argument and modified text by annotation then. The maximum that I get is to do this one thing

CharSequence t = getResources().getString(R.string.tests, "myValue");//in this case i lose my annotation, but set my argument
//OR
CharSequence t = getText(R.string.tests);//in this case i lose my argument but get style BOLD

public SpannableString textFormattingByTags(CharSequence t) {
        SpannedString titleText = new SpannedString(t);
        SpannedString titleText = (SpannedString) getText(R.string.tests);
        Annotation[] annotations = titleText.getSpans(0, titleText.length(), Annotation.class);
        SpannableString spannableString = new SpannableString(titleText);
        for (Annotation annotation : annotations) {
            if (annotation.getKey().equals("font")) {
                String fontName = annotation.getValue();
                if (fontName.equals("bold")) {
                    spannableString.setSpan(new CustomTypefaceSpan("",fontBold),
                            titleText.getSpanStart(annotation),
                            titleText.getSpanEnd(annotation),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        return spannableString;
    }

result in first case i get "Test testBold MyValue end" in second "Test testBold %1$s end". Who had some ideas?

like image 710
mario Avatar asked Aug 09 '18 08:08

mario


People also ask

What is annotated string?

To set different styles within the same Text composable, you have to use an AnnotatedString , a string that can be annotated with styles of arbitrary annotations.

What is formatted string?

String formatting is also known as String interpolation. It is the process of inserting a custom string or variable in predefined text. custom_string = "String formatting" print(f"{custom_string} is a powerful technique") Powered by Datacamp Workspace. String formatting is a powerful technique.

How do you format a string in JavaScript?

JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values (UTF-16 code units). Each element in the String occupies a position in the String. The first element is at index 0, the next at index 1, and so on.


1 Answers

1. Convert arguments to annotations

Your string:

<string name="tests" formatted="true">Test<annotation font="bold"> testBold %1$s</annotation> end</string>

Becomes:

<string name="tests">Test<annotation font="bold"> testBold <annotation arg="0">%1$s</annotation></annotation> end</string>

2. Create SpannableStringBuilder from resource

val text = context.getText(R.string.tests) as SpannedString
val spannableText = SpannableStringBuilder(text)

3. Apply ALL arg annotations FIRST

An example implementation:

fun SpannableStringBuilder.applyArgAnnotations(vararg args: Any) {
    val annotations = this.getSpans(0, this.length, Annotation::class.java)
    annotations.forEach { annotation ->
        when (annotation.key) {
            "arg" -> {
                val argIndex = Integer.parseInt(annotation.value)
                when (val arg = args[argIndex]) {
                    is String -> {
                        this.replace(
                            this.getSpanStart(annotation),
                            this.getSpanEnd(annotation),
                            arg
                        )
                    }
                }
            }
        }
    }
}

Pass in arguments:

spannableText.applyArgAnnotations("myValue")

4. Apply remaining annotations

spannableText.applyAnnotations()
textView.text = spannableText

5. Result

Test testBold myValue end

Edit

Created a small lib to abstract this behaviour - https://github.com/veritas1/tinytextstyler

like image 78
veritas1 Avatar answered Sep 18 '22 10:09

veritas1