เปลี่ยนสีข้อความของคำหนึ่งคำใน TextView


98

ฉันกำลังมองหาวิธีเปลี่ยนสีของข้อความคำเดียวใน a TextViewจากภายในActivityไฟล์.

ตัวอย่างเช่นด้วยสิ่งนี้:

String first = "This word is ";
String next = "red"
TextView t = (TextView) findViewById(R.id.textbox);
t.setText(first + next);

ฉันจะเปลี่ยนสีของnextข้อความเป็นสีแดงได้อย่างไร




คำตอบ:


176

วิธีที่ง่ายที่สุดที่ฉันรู้คือใช้ html

String first = "This word is ";
String next = "<font color='#EE0000'>red</font>";
t.setText(Html.fromHtml(first + next));

แต่สิ่งนี้จะทำให้คุณต้องสร้าง TextView ใหม่เมื่อ (ถ้า?) คุณต้องการเปลี่ยนสีซึ่งอาจทำให้เกิดความยุ่งยาก


1
นี่เป็นวิธีที่ง่ายที่สุด แต่ไม่ควรให้สีเป็น color = '# EE0000' จำเป็นต้องใช้สัญลักษณ์ปอนด์เพื่อแสดงสีฐานสิบหก
ทอม

แก้ไขแล้วขอบคุณ! ฉันจำไม่ได้ว่าฉันคัดลอกสิ่งนี้จากรหัสจริงหรือจากหน่วยความจำด้วยเว็บไซต์ตัวสร้างสีดังนั้นอาจไม่เคยทำงานมาก่อน
แดน

ตกลงแค่แน่ใจ! นอกจากนี้ฉันพบว่าคุณไม่สามารถใช้รหัสฐานสิบหก 8 หลักได้ดังนั้นจึงไม่มีองค์ประกอบอัลฟา สิ่งนั้นทำให้ฉันนิ่งงันไปชั่วขณะ
ทอม

การใช้fromHtmlจะเลิกตอนนี้
อเล็กซ์โจลิก

Html.fromHtmlเลิกใช้แล้ว วิธีนี้ใช้ได้ผลสำหรับฉัน!
coderpc

74
t.setText(first + next, BufferType.SPANNABLE);
Spannable s = (Spannable)t.getText();
int start = first.length();
int end = start + next.length();
s.setSpan(new ForegroundColorSpan(0xFFFF0000), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

คุณต้องใช้ spannable ซึ่งจะช่วยให้คุณสามารถเพิ่มขนาดของข้อความทำให้เป็นตัวหนา ฯลฯ .... แม้แต่ใส่รูปภาพบางรูป


4
คำตอบที่ดีขอบคุณ ในกรณีนี้สามารถใช้ "s.length ()" แทน "start + next.length ()": int end = s.length ();
Oleg

1
เผื่อว่าใครกำลังมองหา Xamarin.Android Solution คุณสามารถกำหนดSpannableStringวัตถุโดยใช้TextFormattedคุณสมบัติของการควบคุมของคุณ
Jamshaid Kamran

ไม่สามารถทำงานได้ จบลงด้วยการแก้ปัญหาของ BK
2b77bee6-5445-4c77-b1eb-4df3e5

1. หากมีการสร้างจะดีกว่าที่จะใช้มันเสมอ 2. อะไรที่ไม่ได้ผลสำหรับคุณ? โซลูชันนี้เก่าเก่ามาก apis บางตัวมีการเปลี่ยนแปลงเพิ่มลบแก้ไขข้อผิดพลาดอะไรที่ทำงานไม่ได้
codeScriber

2
ฉันได้รับjava.lang.String cannot be cast to android.text.Spannableข้อผิดพลาด
lashgar

38

ใช้ SpannableStringBuilder ดังนี้:

SpannableStringBuilder builder = new SpannableStringBuilder();

SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);

SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);

TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);

มีสิ่งใดบ้างที่ฉันสามารถแทนที่new ForegroundColorSpan(Color)เพื่อให้ข้อความคงสีเริ่มต้นเดิม
cjnash

จะเพิ่มข้อความธรรมดา (String) กลาง textview ได้อย่างไร?
Ragavendra M

5

สำหรับสตริงยาวคุณสามารถใช้สิ่งนี้:

String help = getString(R.string.help);
help = help.replace("some word", "<font color='#EE0000'>some word</font>");
txtDesc.setText(Html.fromHtml(help));

3

หากคุณต้องการเปลี่ยนสถานะของอินสแตนซ์ทั้งหมดที่ระบุStringภายในTextViewข้อความ (ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่) คุณสามารถใช้StringBuilders และทำSpannableStringดังนี้:

StringBuilder textBuilder = new StringBuilder(myTextView.getText().toString());
StringBuilder searchedTextBuilder = new StringBuilder((mySearchedString));
SpannableString spannableString = new SpannableString(myTextView.getText().toString());

int counter = 0;
int index = 0;

for (int i = 0;i < textBuilder.length() - mySearchedString.length() - 1;i++)
{
    counter = 0;
    if (Character.toLowerCase(textBuilder.charAt(i)) == Character.toLowerCase(searchedTextBuilder.charAt(index)))
    {
        counter++;
        index++;
        for (int j = 1,z = i + 1;j < mySearchedString.length() - 1;j++,z++)
        {
            if (Character.toLowerCase(textBuilder .charAt(z)) == Character.toLowerCase(searchedTextBuilder .charAt(index)))
            {
                counter++;
                index++;
            }
            else
            {
                index++;
                if (index % mySearchedString.length() == 0)
                {
                    index = 0;
                }
                break;
             }
        }
        if (counter == mySearchedString.length() - 1) // A match
        {
            spannableString.setSpan(new ForegroundColorSpan(Color.RED), i,
                                i + mySearchedString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Do the change you want(In this case changing the fore ground color to red)
            index = 0;
            continue;
        }
        else
        {
            index = 0;
            continue;
        }
    }
}
myTextView.setText(spannableString);

}

  • จัดเก็บTextViewข้อความทั้งหมดไว้ในไฟล์StringBuilder.
  • เก็บสตริงที่ค้นหาไว้ในไฟล์StringBuilder.
  • จัดเก็บTextViewข้อความทั้งหมดไว้ในไฟล์SpannableString
  • ดำเนินการง่ายๆเพื่อค้นหาStringอินสแตนซ์ทั้งหมดในTextViewข้อความและเปลี่ยนเมื่อถึง
  • ตั้งค่าข้อความเป็นTextViewไฟล์SpannableString.

1

ฉันใช้ฟังก์ชันยูทิลิตี้ใน Kotlin สำหรับกรณีการใช้งานของฉันเองและอาจเป็นประโยชน์สำหรับคนอื่น

fun getCusomTextWithSpecificTextWithDiffColor(textToBold: String, fullText: String,
                                                  targetColor: Int) =
            SpannableStringBuilder(fullText).apply {
                setSpan(ForegroundColorSpan(targetColor),
                        fullText.indexOf(textToBold),
                        (fullText.indexOf(textToBold) + textToBold.length),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }

ฉันใช้มันอย่างไร:

context?.let {
        infoMessage.text = AppUtils.getCusomTextWithSpecificTextWithDiffColor(
                wordAsBold,
                completeSentence, ContextCompat.getColor(it, R.color.white))
    }

1

ใช้:

makeTextBold("Your order is accepted","accepted", textView);
makeTextBold("Your order is canceled","canceled", textView);

ฟังก์ชัน:

public static void makeTextBold(String sentence, String word, AppCompatTextView textView) {
    SpannableStringBuilder builder = new SpannableStringBuilder();
    int startIndex = sentence.indexOf(word.toLowerCase().trim());
    int endIndex = startIndex + word.toLowerCase().trim().length();
    SpannableString spannableString = new SpannableString(sentence);
    StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
    spannableString.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To make text Bold
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To change color of text
    builder.append(spannableString);
    textView.setText(builder, TextView.BufferType.SPANNABLE);
}

0

ฉันคิดว่าสิ่งนี้สามารถอ่านได้มากกว่าสำหรับการระบายสีคำในสตริงซึ่งอาจมีประสิทธิภาพมากกว่าเล็กน้อยเพราะคุณเขียนครั้งเดียว

    String str  = YOUR_STRING
    Spannable s = new SpannableString(str);
    int start = str.indexOf(err_word_origin);
    int end =  start + err_word_origin.length();
    s.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    YOUR_TEXT_VIEW.setText(s , TextView.BufferType.SPANNABLE);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.