如何在安卓中部分更改文本颜色

3

我有一个包含要发送到服务器的消息的句子,例如wow! superb pic #superb #pic #111 #222 enjoyed the pic

我想提取hastags并使它们变成彩色,同时保留其余文本不变。

我尝试了以下代码但没有成功。

private void spannableOperationOnHastag() {
        mPostMessage = edPostMessage.getText().toString().trim();
        String strPreHash = null;
        String strHashText = "";
        if (mPostMessage.contains("#")) {
            try {
                int index = mPostMessage.indexOf("#");
                strPreHash = mPostMessage.substring(0, index);
                SpannableString spannableString = new SpannableString(strPreHash);


                String strHashDummy=mPostMessage.substring(index, mPostMessage.length());
                int hashCount= StringUtils.countMatches(strHashDummy, "#"); // check for number of "#" occurrence and run forloop for getting the number of hastags in the string
                int hasIndex=0;
                for (int i = 0; i <hashCount ; i++) {
                    strHashText = strHashText+strHashDummy.substring(hasIndex, strHashDummy.indexOf(' '))+" ";
                    hasIndex =strHashText.indexOf(" "); // updating new space(" ") position in the index variable
                }


                SpannableString spannableStringBlue = new SpannableString(strHashText);
                spannableStringBlue.setSpan(new ForegroundColorSpan(PublishPostActivity.this.getResources().getColor(R.color.blue)), 0, strHashText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                edPostMessage.setText(null); // clearing old string
                edPostMessage.append(spannableString); // setting extracted coloured text
                edPostMessage.append(spannableStringBlue);
            } catch (Exception e) {
                Log.d(TAG, "validatePostMessage() called with " + "e = [" + e + "]");
            }
        }
    }
4个回答

1
我自己解决了这个问题。如有需要,可以参考此代码:)
private void spannableOperationOnHastag() throws Exception{
        mPostMessage = edPostMessage.getText().toString()+" "; // extra space for spannable operations
        List<Integer> listStartPos = new ArrayList<>();
        List<Integer> listEndtPos = new ArrayList<>();

        if (mPostMessage.contains("#")){
            for (int i = 0; i < mPostMessage.length(); i++) {
                if (mPostMessage.charAt(i) == '#') {
                    listStartPos.add(i);
                    Log.d(TAG, "startIndex of # = " + i);
                }
            }
            for (int i = 0; i < listStartPos.size(); i++) {
                int endIndex = mPostMessage.indexOf(' ', listStartPos.get(i));
                listEndtPos.add(endIndex);
                Log.d(TAG, "endIndex of # " + (endIndex));
            }
            SpannableString spanned = SpannableString.valueOf(mPostMessage);
            for (int i = 0; i < listStartPos.size(); i++) {
                spanned = new SpannableString(spanned);
                spanned.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.blue)), listStartPos.get(i), listEndtPos.get(i), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                Log.d(TAG, "substring " + mPostMessage.substring(listStartPos.get(i), listEndtPos.get(i) + 1));
            }
            mPostMessage.trim(); // removing extra space.
            edPostMessage.setText(null);
            edPostMessage.setText(spanned);

        }
    }

1

我看到你刚刚发布了自己的答案,但是由于我已经快打完这个答案,所以我还是决定把它发布出来:)。我刚刚在没有IDE的情况下打出了这个答案,可能不是完美的。

private static SpannableString convertTextColorsAtChar(char trigger, String inputText) {

    SpannableString spannedText = new SpannableString(inputText);

    if (!inputText.contains(trigger)) {
        return spannedText;
    }

    ArrayList<int[]> indexArr = getIndexes(trigger, inputText.toCharArray());

    for (int[] indexes : indexArr) {
        spannedText.setSpan(new ForegroundColorSpan(Color.RED), indexes[0], indexes[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    returned spannedText;

}

private static ArrayList<int[]> getIndexes(char trigger, char[] inputText) {

    ArrayList<int[]> values = new ArrayList<int[]>();

    int firstIndex = -1;
    int secondIndex; = -1

    for (int i = 0; i < inputText.length; i++) {
        if (firstIndex != -1 && inputText[i] == ' ') {
            secondIndex = i;
            values.add(new int[] { firstIndex, secondIndex });
            firstIndex = secondIndex = -1;
        }
        if (trigger == inputText[i]) {
            firstIndex = i;
        }
    }

    return values;

}

您需要使用convertTextColorsAtChar('#', editText.getText().toString());来调用它。


0

请将您的代码更改为以下内容

SpannableString spannableStringBlue = new SpannableString(strHashText);

 spannableStringBlue.setSpan(new ForegroundColorSpan(new ForegroundColorSpan(Color.BLUE), 0, strHashText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

edPostMessage.setText(null); // clearing old string
edPostMessage.append(spannableString); // setting extracted coloured text
edPostMessage.append(spannableStringBlue);

看代码似乎不完整。在句子中间可能会有许多井号。我想要着色所有的井号,而不是字符串的其他部分。 - karthik kolanji
我刚刚更改了你的颜色部分...在可扩展文本中...你必须自己实现逻辑。 - H Raval

0
SpannableStringBuilder builder = new SpannableStringBuilder();
String yourSentence = "Pic #superb #pic #111 #222 enjoyed the pic";
String [] newSent = yourSentence.split(" ");

    for(int count = 0; count < newSent.length; count++){
       if(newSent[count].contains("#")){
          SpannableString redSpannable= new SpannableString(newSent[count]);
          redSpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, newSent[count].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

          Log.v("Test", "color_string" + newSent[count]);
          builder.append(redSpannable+" ");
        } else{
          builder.append(newSent[count]+" ");
          Log.v("Test", "normal_string" + newSent[count]);
          }
       }

    holder.PhName.setText(builder, TextView.BufferType.SPANNABLE);

它将仅替换“#”而不是“#superb”。 - karthik kolanji
现在?我已经编辑了我的答案。或者,您可以将所有#后的子字符串放入数组中,并像我所做的那样进行替换。 - Niraj Niroula
那么,我认为你应该使用'SpannableString'。请查看@H Raval的答案。我也会看一下。 - Niraj Niroula

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接