Single TextView พร้อมข้อความหลายสี


167

ตามที่ชื่อบอกว่าฉันต้องการทราบว่าเป็นไปได้หรือไม่ที่จะบรรลุตัวละครสองสีที่ต่างกันในองค์ประกอบมุมมองข้อความเดียว



1
มันไม่ซ้ำกันเนื่องจากผู้ถามจะขอสีโดยเฉพาะ
อิกบัล

มีห้องสมุดที่ดีสำหรับสิ่งนี้ฉันคิดว่า: blog.stylingandroid.com/rialto-downloadable-fonts github.com/StylingAndroid/Rialto
นักพัฒนา Android

ฉันได้เขียนห้องสมุดบางส่วนด้วยซึ่งมีพฤติกรรมคล้ายกันนี้: github.com/ha-yi/MultiColorTextView
Hayi Nukman

คำตอบ:


328

ใช่ถ้าคุณจัดรูปแบบStringกับhtmlของfont-colorสถานที่ให้บริการแล้วผ่านไปยังวิธีการHtml.fromHtml(your text here)

String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));

ขอบคุณยังเป็นประโยชน์สำหรับฉัน +1
Hardik Joshi

10
อย่าลืมที่จะหลบหนี userinput Html.escapeHtml(str)ใช้
kelunik

1
เพิ่มใน api ระดับ 1
2red13

3
เพียงแค่คำเตือน ฉันมีปัญหาเมื่อฉันต้องการให้ข้อความของฉันเป็นตัวพิมพ์ใหญ่ ฉันใช้ android: textAllCaps = "true" ใน XML และในเวลาเดียวกันมีเนื้อหา HTML ของฉันเป็นตัวพิมพ์ใหญ่ มันไม่ทำงาน ฉันลบแอตทริบิวต์ XML และตอนนี้ทำงานได้ดี ระวังเพราะถ้าคุณใช้ setAllCaps () ในรหัสปัญหาเดียวกันจะปรากฏขึ้น
joao2fast4u

5
Html.fromHtml(String)Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY)จะเลิกตอนนี้แทนที่จะใช้ ข้อมูลเพิ่มเติมสามารถดูได้ที่นี่.
JediBurrell

165

คุณสามารถพิมพ์เส้นที่มีหลายสีโดยไม่มี HTML ดังนี้

TextView textView = (TextView) findViewById(R.id.mytextview01);
Spannable word = new SpannableString("Your message");        

word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(word);
Spannable wordTwo = new SpannableString("Your new message");        

wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(wordTwo);

ยอดเยี่ยมขอบคุณยังสามารถทำ BackgroundColorSpan มีตัวพิมพ์เล็ก ๆ ในตัวอย่างของคุณคือ WordToSpan และ WordtoSpan ให้สังเกตกรณีใน To
steveh

วิธีการหนึ่งที่เกี่ยวกับการทดสอบหน่วยมุมมองข้อความเพื่อให้แน่ใจว่าข้อความลงท้ายด้วย Color.RED stackoverflow.com/questions/26611533/…
sudocoder

1
ไม่ทำงานสำหรับฉันที่ได้รับ `java.lang.StringIndexOutOfBoundsException: length = 3; index = 12`
Muhammad Babar

1
StringIndexOutOfBoundsExceptionอธิบายตนเอง คุณกำลังเข้าถึงสตริงที่เกินความยาว
Swapnil Kotwal

1
สตริงของฉันไม่ได้รับการแก้ไขดังนั้นสตริงจะสร้างในเวลาทำงานของแอพ ฉันได้ลองคำตอบของคำถามนี้เกือบทั้งหมดแล้ว แต่วิธีนี้ใช้ได้สำหรับฉันเท่านั้น
Md. Sabbir Ahmed

33

คุณสามารถใช้Spannableเพื่อใช้เอฟเฟกต์กับTextView:

นี่คือตัวอย่างของฉันสำหรับการระบายสีเพียงส่วนแรกของTextViewข้อความ (ในขณะที่อนุญาตให้คุณตั้งค่าสีแบบไดนามิกแทนที่จะเขียนโค้ดลงในสตริงอย่างยากลำบากเช่นเดียวกับตัวอย่างของ HTML!)

    mTextView.setText("Red text is here", BufferType.SPANNABLE);
    Spannable span = (Spannable) mTextView.getText();
    span.setSpan(new ForegroundColorSpan(0xFFFF0000), 0, "Red".length(),
             Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

ในตัวอย่างนี้คุณสามารถแทนที่ 0xFFFF0000 ด้วย getResources().getColor(R.color.red)


1
หากคุณต้องการตัวพิมพ์ใหญ่นี้เพียงไปที่ UpperCase () the Strings
แกรม

33

ฉันทำแบบนี้แล้ว:

ตรวจสอบการอ้างอิง

ชุดสีบนข้อความโดยผ่าน Stringและสี :

private String getColoredSpanned(String text, String color) {
    String input = "<font color=" + color + ">" + text + "</font>";
    return input;
}

ตั้งค่าข้อความบนTextView / ปุ่ม / EditText และอื่น ๆ โดยเรียกรหัสด้านล่าง:

TextView:

TextView txtView = (TextView)findViewById(R.id.txtView);

รับสายสี:

String name = getColoredSpanned("Hiren", "#800000");
String surName = getColoredSpanned("Patel","#000080");

ตั้งค่า Text บน TextView ของสองสายที่มีสีต่างกัน:

txtView.setText(Html.fromHtml(name+" "+surName));

เสร็จสิ้น


1
nyc one แต่ HTml.fromHtml เลิกใช้แล้วจาก API 24
Anuraj R

คุณสามารถแทนที่การโทรHtml.fromHtml("...")ด้วยการโทรไปที่Html.fromHtml("...", FROM_HTML_MODE_LEGACY)
stkent

31

ใช้ 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);

8

เฮ้พวกฉันทำไปแล้วลองดู

TextView textView=(TextView)findViewById(R.id.yourTextView);//init

//here I am appending two string into my textView with two diff colors.
//I have done from fragment so I used here getActivity(), 
//If you are trying it from Activity then pass className.this or this; 

textView.append(TextViewUtils.getColoredString(getString(R.string.preString),ContextCompat.getColor(getActivity(),R.color.firstColor)));
textView.append(TextViewUtils.getColoredString(getString(R.string.postString),ContextCompat.getColor(getActivity(),R.color.secondColor)));

ภายในคุณ TextViewUtils คลาสเพิ่มวิธีนี้

 /***
 *
 * @param mString this will setup to your textView
 * @param colorId  text will fill with this color.
 * @return string with color, it will append to textView.
 */
public static Spannable getColoredString(String mString, int colorId) {
    Spannable spannable = new SpannableString(mString);
    spannable.setSpan(new ForegroundColorSpan(colorId), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    Log.d(TAG,spannable.toString());
    return spannable;
}

ฉันได้อัปเดตทันทีตรวจสอบอีกครั้งมันใช้งานได้สำหรับฉัน
Abdul Rizwan

Myabe คุณใช้ Html.fromHtml เพื่อใช้สตริงนี้หรือไม่?
Sergey Shustikov

ภายในไฟล์ string.xml ฉันได้สร้างตัวแปรแล้วตั้งค่ามันทำงานได้สำหรับฉันตอนนี้ฉันกำลังทำอยู่คุณช่วยให้สตริงที่นี่ได้ไหม
Abdul Rizwan

5

จะดีกว่าถ้าใช้สตริงในไฟล์ strings เช่น:

    <string name="some_text">
<![CDATA[
normal color <font color=\'#06a7eb\'>special color</font>]]>
    </string>

การใช้งาน:

textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)

4

ฉันได้เขียนโค้ดสำหรับคำถามอื่นที่คล้ายกับคำถามนี้ แต่คำถามนั้นมีการทำซ้ำดังนั้นฉันจึงไม่สามารถตอบได้ที่นั่นดังนั้นฉันแค่วางรหัสของฉันที่นี่ถ้ามีคนมองหาข้อกำหนดเดียวกัน

รหัสไม่ทำงานอย่างสมบูรณ์คุณต้องทำการเปลี่ยนแปลงเล็กน้อยเพื่อให้ทำงานได้

นี่คือรหัส:

ฉันใช้แนวคิด @Graeme ว่าด้วยการใช้ข้อความที่อ่านง่าย

String colorfulText = "colorfulText";       
    Spannable span = new SpannableString(colorfulText);             

    for ( int i = 0, len = colorfulText.length(); i < len; i++ ){
        span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                     
    }   

    ((TextView)findViewById(R.id.txtSplashscreenCopywrite)).setText(span);

วิธีการสีแบบสุ่ม:

  private int getRandomColor(){
        Random rnd = new Random();
        return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
    }

2

ลองสิ่งนี้:

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
      "<small>" + description + "</small>" + "<br />" + 
      "<small>" + DateAdded + "</small>"));

2

ใช้คลาส SpannableBuilder แทนการจัดรูปแบบ HTML ที่เป็นไปได้เพราะเร็วกว่าการแยกวิเคราะห์รูปแบบ HTML ดูมาตรฐานของฉัน "SpannableBuilder vs HTML" บนGithub ขอบคุณ!


1

คำตอบที่ยอดเยี่ยม! ฉันสามารถใช้ Spannable เพื่อสร้างข้อความสีรุ้ง (ดังนั้นจึงสามารถทำซ้ำได้สำหรับสีต่างๆ) นี่คือวิธีการของฉันถ้ามันช่วยทุกคน:

private Spannable buildRainbowText(String pack_name) {
        int[] colors = new int[]{Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE};
        Spannable word = new SpannableString(pack_name);
        for(int i = 0; i < word.length(); i++) {
            word.setSpan(new ForegroundColorSpan(colors[i]), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return word;
    }

แล้วฉันเพิ่ง setText (buildRainboxText (pack_name)); โปรดทราบว่าคำทั้งหมดที่ฉันส่งผ่านมีความยาวไม่เกิน 15 ตัวอักษรและนี่จะทำซ้ำ 5 สี 3 ครั้ง - คุณต้องการปรับสี / ความยาวของอาร์เรย์สำหรับการใช้งานของคุณ!


1
if (Build.VERSION.SDK_INT >= 24) {
     Html.fromHtml(String, flag) // for 24 API  and more
 } else {
     Html.fromHtml(String) // or for older API 
 }

สำหรับ 24 API และอื่น ๆ (ตั้งค่าสถานะ)

public static final int FROM_HTML_MODE_COMPACT = 63;
public static final int FROM_HTML_MODE_LEGACY = 0;
public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;

ข้อมูลเพิ่มเติม


1

ตั้งแต่ API 24 คุณมี FROM_HTML_OPTION_USE_CSS_COLORS เพื่อให้คุณสามารถกำหนดสีใน CSS แทนการทำซ้ำตลอดเวลาด้วยfont color=" Very clearer - เมื่อคุณมี html บางตัวและคุณต้องการเน้นแท็กที่กำหนดไว้ล่วงหน้า - คุณเพียงแค่เพิ่มส่วน CSS ที่ด้านบนของ html


0

25 มิถุนายน 2020 โดย @canerkaseler

ฉันต้องการแบ่งปันKotlin คำตอบ :

fun setTextColor(tv:TextView, startPosition:Int, endPosition:Int, color:Int){
    val spannableStr = SpannableString(tv.text)

    val underlineSpan = UnderlineSpan()
    spannableStr.setSpan(
        underlineSpan,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    val backgroundColorSpan = ForegroundColorSpan(this.resources.getColor(R.color.agreement_color))
    spannableStr.setSpan(
        backgroundColorSpan,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    val styleSpanItalic = StyleSpan(Typeface.BOLD)
    spannableStr.setSpan(
        styleSpanItalic,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    tv.text = spannableStr
}

หลังจากนั้นเรียกฟังก์ชั่นดังกล่าวข้างต้น คุณสามารถโทรมากกว่าหนึ่ง:

setTextColor(textView, 0, 61, R.color.agreement_color)
setTextColor(textView, 65, 75, R.color.colorPrimary)

ผลลัพธ์: คุณสามารถเห็นขีดเส้นใต้และสีที่ต่างกัน

@canerkaseler

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.