Android TextView format multiple words

≡放荡痞女 提交于 2019-12-06 09:03:39

问题


Original String:

Lorem ##ipsum## dolar ##sit## atem. Lorem ipsum dolar sit ##atem##.

After formating:

Lorem #ipsum dolar #sit atem. Lorem ipsum dolar sit #atem.

But only the last one has the Formating i want. See image below.

CODE

private void format() {
    CharSequence text = editContent.getText();

    MovementMethod movementMethod = editContent.getMovementMethod();
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod))
    {
        editContent.setMovementMethod(LinkMovementMethod.getInstance());
    }

    text = setSpanBetweenTokens(text, "##", new ForegroundColorSpan(0xFF0099FF), new UnderlineSpan(), new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show();
        }
    });

    editContent.setText(text);
}

private static CharSequence setSpanBetweenTokens(CharSequence text, String token, CharacterStyle... characterStyle) {
    int tokenLen = token.length();
    int start = text.toString().indexOf(token) + 1;
    int end = text.toString().indexOf(token, start);

    while (start > -1 && end > -1)
    {
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
        for (CharacterStyle c : characterStyle) {
            spannableStringBuilder.setSpan(c, start, end, 0);
        }

        spannableStringBuilder.delete(end, end + tokenLen);
        spannableStringBuilder.delete(start - 1, start);

        text = spannableStringBuilder;

        start = text.toString().indexOf(token) + 1;
        end = text.toString().indexOf(token, start);
    }

    return text;
}

EDIT

My final Solution

private void format() {
    CharSequence text = editContent.getText();

    MovementMethod movementMethod = editContent.getMovementMethod();
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod))
    {
        editContent.setMovementMethod(LinkMovementMethod.getInstance());
    }

    text = setSpanBetweenTokens(text, "##");

    editContent.setText(text);
}

private static CharSequence setSpanBetweenTokens(CharSequence text, String token) {
    int tokenLen = token.length();
    int start = text.toString().indexOf(token) + 1;
    int end = text.toString().indexOf(token, start);

    while (start > -1 && end > -1)
    {
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);

        spannableStringBuilder.setSpan(new ForegroundColorSpan(0xFF0099FF), start, end, 0);
        spannableStringBuilder.setSpan(new UnderlineSpan(), start, end, 0);
        spannableStringBuilder.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Log.d("DEBUG", "Click");
            }
        }, start, end, 0);

        spannableStringBuilder.delete(end, end + tokenLen);
        spannableStringBuilder.delete(start - 1, start);

        text = spannableStringBuilder;

        start = text.toString().indexOf(token) + 1;
        end = text.toString().indexOf(token, start);
    }

    return text;
}

回答1:


Pass different object for each span:

spannableStringBuilder.setSpan(c, start, end, 0);

You're passing the same object for each span:

new ForegroundColorSpan(0xFF0099FF)

When span object exists in spannableStringBuilder then it changes bounds only, not a new span is added.




回答2:


I would suggest a simpler way. If your formatting needs are basic, a simple regex + Html.fromHtml() should do the trick:

private void format() {
    String mText = editContent.getText();

    Spanned mSpannedText = Html.fromHtml(mText.replaceAll("##(.*?)##)","<font color=\"0xFF0099\">#$1</font>"), 

    editContent.setText(mSpannedText);
}



回答3:


The final solution correctly loops however your first token will not be correctly deleted as you have used

int start = text.toString().indexOf(token) + 1;

which would only work if your token was 1 character in length. Since your chosen token is ## change the above code to utilise the already created variable tokenLen

int start = text.toString().indexOf(token) + tokenLen;

this will ensure your text is correctly edited and all trace of your tokens are removed.



来源:https://stackoverflow.com/questions/9973764/android-textview-format-multiple-words

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!