ฉันจะเปลี่ยนสีของส่วนของ TextView ได้อย่างไร?


110
text = text + CepVizyon.getPhoneCode() + "\n\n"
            + getText(R.string.currentversion) + CepVizyon.getLicenseText();
    activationText.setText(text);   
myTextView.setText(text);

ฉันต้องการเปลี่ยนสีสำหรับCepVizyon.getPhoneCode()สตริงของ ฉันจะทำเช่นนี้ได้อย่างไร?


ดูสิ่งนี้: stackoverflow.com/questions/4897349/…
live-love


คำถามนั้นถูกถาม 19 ก.ค. 53 เวลา 16:27 น. ประมาณ 3 เดือนก่อนคุณ อย่างไรก็ตามมันไม่ใช่โพสต์ที่เก่าแก่ที่สุดที่จะต้องเป็นเป้าหมายที่ซ้ำกันเสมอไป ควรคำนึงถึงจำนวนการดูจำนวนการโหวตจำนวนคำตอบและความชัดเจนของคำถาม การทำเครื่องหมายว่าซ้ำจะช่วยให้ผู้อื่นพบคำตอบอื่น ๆ ที่ตอบคำถามของคุณได้เช่นกัน
Suragch


เพื่อให้เข้าใจถึงเบื้องหลังจริงๆฉันขอแนะนำให้อ่านบทความเชิงลึกเช่นนี้: medium.com/androiddevelopers/…
Michal Vician

คำตอบ:


175

Spannableมีความยืดหยุ่นมากขึ้น:

String text2 = text + CepVizyon.getPhoneCode() + "\n\n"
            + getText(R.string.currentversion) + CepVizyon.getLicenseText();

Spannable spannable = new SpannableString(text2);

spannable.setSpan(new ForegroundColorSpan(Color.WHITE), text.length(), (text + CepVizyon.getPhoneCode()).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

myTextView.setText(spannable, TextView.BufferType.SPANNABLE);

3
ขอบคุณสำหรับคำตอบนี้! นี่เป็นเหมือน NSAttributedString ใน iOS :) เพื่อให้ยืดหยุ่นยิ่งขึ้นให้แทนที่ text.lenght ด้วย text2.indexOf (CepVizyon.getPhoneCode ()) ซึ่งช่วยให้คุณไม่ทราบส่วนแรกของ String
iGranDav

1
คุณควรใส่()after text.lengthas lengthis เป็นวิธีการไม่ใช่ฟิลด์ จะทำเอง แต่การแก้ไขต้องมีอย่างน้อย 6 ตัวอักษร :)
MSX

1
ปัญหาของ Spannable คือ ellipsize = end ไม่ทำงานอีกต่อไป ซึ่งเป็นปัญหาร้ายแรงในบางกรณี
Juan Carlos Ospina Gonzalez

1
ใช้งานได้ดี แม้ว่าจะแนะนำให้สร้างสตริง HTML จากนั้นแยกวิเคราะห์ผ่านคลาส HTML Html.fromHtml(R.id.your_html_string);
sud007

การเปลี่ยนสีของขีดเส้นใต้ (หาก textview มีค่าสถานะขีดเส้นใต้) มีวิธีใดในการป้องกัน
ยกเลิก

73
myTextView.setText(Html.fromHtml(text + "<font color=white>" + CepVizyon.getPhoneCode() + "</font><br><br>"
            + getText(R.string.currentversion) + CepVizyon.getLicenseText()));

65

หากคุณมีข้อความคงที่ที่ต้องการสีคุณสามารถเพิ่มได้โดยไม่ต้องใช้รหัสผ่านไฟล์สตริง:

<string name="already_have_an_account">Already have an account? <font color='#01C6DB'>Login</font></string>

แล้ว

<TextView
    android:layout_width="wrap_content"
    android:layout_height="64dp"
    android:text="@string/already_have_an_account"/>

ผลลัพธ์

ป้อนคำอธิบายภาพที่นี่

ไม่แน่ใจว่าเวอร์ชัน api ใดที่ใช้งานได้ แต่ใช้งานไม่ได้กับ api 19 ที่ทดสอบแล้วดังนั้นอาจมีเพียงเวอร์ชัน api ล่าสุดบางรุ่นเท่านั้นที่รองรับสิ่งนี้

แก้ไข: ตามที่ @hairraisin กล่าวถึงในความคิดเห็นลองใช้fgcolorแทนcolorสีแบบอักษรจากนั้นควรใช้กับระดับ api ที่ต่ำกว่า แต่ต้องการการทดสอบเพิ่มเติมเพื่อให้แน่ใจ


3
ฉันทดสอบโดยใช้<font fgcolor=...API 15 และ API 25 สำเร็จแล้ว (ฉันไม่ได้ทดสอบโดยเฉพาะ 19)
ลูกเกด

ไม่ทำงานเมื่อฉันตั้งค่าข้อความโดยใช้โปรแกรม :(
Rohit Singh

นี่ไม่ใช่วิธีการแก้ปัญหาที่ดีเนื่องจากการแปลผสมกับสีข้อความ
MilošČernilovský

16

สำหรับคำตอบของ Maneesh สิ่งนี้จะได้ผล แต่คุณต้องเพิ่มและหลีกเลี่ยงเครื่องหมายคำพูดสำหรับแอตทริบิวต์ color

myTextView.setText(Html.fromHtml(text + "<font color=\"#FFFFFF\">" + CepVizyon.getPhoneCode() + "</font><br><br>"
            + getText(R.string.currentversion) + CepVizyon.getLicenseText()));

8

มันดีสำหรับฉัน!

            Spannable spannable = new SpannableString("ABC In-Network DEF");
            String str = spannable.toString();
            iStart = str.indexOf("In-Network");
            iEnd = iStart + 10;/*10 characters = in-network. */

            SpannableString ssText = new SpannableString(spannable);
            ClickableSpan clickableSpan = new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    //your code at here.
                }

                @Override
                public void updateDrawState(TextPaint ds) {
                    super.updateDrawState(ds);
                    ds.setUnderlineText(true);
                    ds.setColor(getResources().getColor(R.color.green));
                }
            };
            ssText.setSpan(clickableSpan, iStart, iEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mTextView.setText(ssText);
            mTextView.setMovementMethod(LinkMovementMethod.getInstance());
            mTextView.setHighlightColor(Color.TRANSPARENT);
            mTextView.setEnabled(true);

7

นี่คือวิธีแก้ปัญหาใน Kotlin ที่ใช้SpannableStringในการเปลี่ยนสีของส่วนหนึ่งของสตริง

    val phoneCodeColor = ContextCompat.getColor(this, R.color.myColor)
    val text = SpannableStringBuilder()
        .color(phoneCodeColor) { append("${ CepVizyon.getPhoneCode() }") }
        .append("\n\n")
        .append(getString(R.string.currentversion))
        .append(${ CepVizyon.getLicenseText() })

    activationText.text = text
    myTextView.text = text

6

นี่คือcolorizeฟังก์ชั่นตามคำตอบของ andyboot:

 /**
 * Colorize a specific substring in a string for TextView. Use it like this: <pre>
 * textView.setText(
 *     Strings.colorized("The some words are black some are the default.","black", Color.BLACK),
 *     TextView.BufferType.SPANNABLE
 * );
 * </pre>
 * @param text Text that contains a substring to colorize
 * @param word The substring to colorize
 * @param argb The color
 * @return the Spannable for TextView's consumption
 */
public static Spannable colorized(final String text, final String word, final int argb) {
    final Spannable spannable = new SpannableString(text);
    int substringStart=0;
    int start;
    while((start=text.indexOf(word,substringStart))>=0){
        spannable.setSpan(
                new ForegroundColorSpan(argb),start,start+word.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        );
        substringStart = start+word.length();
    }
    return spannable;
}

4

ฉันไม่ชอบความคิดในการทำสิ่งนี้ด้วยรหัสทุกครั้งที่ฉันต้องการระบายสีส่วนของข้อความที่ฉันทำมามากมายในแอพทั้งหมดของฉัน (และเนื่องจากในบางกรณีข้อความจะถูกตั้งค่าในรันไทม์ด้วยอินไลน์ที่แตกต่างกัน - สีที่กำหนด) MarkableTextViewดังนั้นผมจึงสร้างของตัวเอง

แนวคิดคือ:

  • ตรวจหาแท็ก XML จากสตริง
  • ระบุและจับคู่ชื่อแท็ก
  • แยกและบันทึกแอตทริบิวต์และตำแหน่งของข้อความ
  • ลบแท็กและเก็บเนื้อหา
  • วนซ้ำผ่านแอตทริบิวต์และใช้สไตล์

นี่คือกระบวนการทีละขั้นตอน:

ก่อนอื่นฉันต้องการวิธีค้นหาแท็ก XML ในสตริงที่กำหนดและRegexทำเคล็ดลับ ..

<([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)(?:\s+([^>]*))?>([^>][^<]*)</\1\s*>

เพื่อให้ตรงกับแท็ก XML ข้างต้นจะต้องมีเกณฑ์ดังต่อไปนี้:

  • ชื่อแท็กที่ถูกต้องเหมือน<a> <a > <a-a> <a ..attrs..>แต่ไม่ใช่< a> <1>
  • แท็กปิดที่มีชื่อตรงกันเช่น <a></a>แต่ไม่ใช่<a></b>
  • เนื้อหาใด ๆ เนื่องจากไม่จำเป็นต้องจัดรูปแบบ "ไม่มีอะไร"

ตอนนี้สำหรับคุณสมบัติเราจะใช้อันนี้ ..

([a-zA-Z]+)\s*=\s*(['"])\s*([^'"]+?)\s*\2

มีแนวคิดเหมือนกันและโดยทั่วไปฉันไม่จำเป็นต้องไปไกลสำหรับทั้งคู่เนื่องจากคอมไพเลอร์จะดูแลส่วนที่เหลือหากมีสิ่งใดผิดรูปแบบ

ตอนนี้เราต้องการคลาสที่สามารถเก็บข้อมูลที่แยกได้:

public class MarkableSheet {

    private String attributes;
    private String content;
    private int outset;
    private int ending;
    private int offset;
    private int contentLength;

    public MarkableSheet(String attributes, String content, int outset, int ending, int offset, int contentLength) {

        this.attributes = attributes;
        this.content = content;
        this.outset = outset;
        this.ending = ending;
        this.offset = offset;
        this.contentLength = contentLength;
    }

    public String getAttributes() {
        return attributes;
    }

    public String getContent() {
        return content;
    }

    public int getOutset() {
        return outset;
    }

    public int getContentLength() {
        return contentLength;
    }

    public int getEnding() {
        return ending;
    }

    public int getOffset() {
        return offset;
    }
}

ก่อนอื่นเราจะเพิ่มตัววนซ้ำสุดเจ๋งที่ฉันใช้มานานเพื่อวนรอบการแข่งขัน (จำผู้แต่งไม่ได้) :

public static Iterable<MatchResult> matches(final Pattern p, final CharSequence input) {

        return new Iterable<MatchResult>() {

            public Iterator<MatchResult> iterator() {

                return new Iterator<MatchResult>() {

                    // Use a matcher internally.
                    final Matcher matcher = p.matcher(input);

                    // Keep a match around that supports any interleaving of hasNext/next calls.
                    MatchResult pending;

                    public boolean hasNext() {

                        // Lazily fill pending, and avoid calling find() multiple times if the
                        // clients call hasNext() repeatedly before sampling via next().
                        if (pending == null && matcher.find()) {
                            pending = matcher.toMatchResult();
                        }
                        return pending != null;
                    }

                    public MatchResult next() {

                        // Fill pending if necessary (as when clients call next() without
                        // checking hasNext()), throw if not possible.
                        if (!hasNext()) { throw new NoSuchElementException(); }

                        // Consume pending so next call to hasNext() does a find().
                        MatchResult next = pending;
                        pending = null;

                        return next;
                    }

                    /** Required to satisfy the interface, but unsupported. */
                    public void remove() { throw new UnsupportedOperationException(); }
                };
            }
        };
    }

MarkableTextView:

public class MarkableTextView extends AppCompatTextView {

    public MarkableTextView(Context context) {
        super(context);
    }

    public MarkableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MarkableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {

        // Intercept and process text
        text = prepareText(text.toString());

        super.setText(text, type);
    }

    public Spannable Markable;

    private Spannable prepareText(String text) {

        String parcel = text;
        Multimap<String, MarkableSheet> markableSheets = ArrayListMultimap.create();

        // Used to correct content position after tossing tags
        int totalOffset = 0;

        // Iterate through text
        for (MatchResult match : matches(Markable.Patterns.XML, parcel)) {

            // Get tag name
            String tag = match.group(1);

            // Match with a defined tag name "case-sensitive"
            if (!tag.equals(Markable.Tags.MARKABLE)) {

                // Break if no match
                break;
            }

            // Extract data
            String attributes = match.group(2);
            String content = match.group(3);

            int outset = match.start(0);
            int ending = match.end(0);
            int offset = totalOffset; // offset=0 since no preceded changes happened
            int contentLength = match.group(3).length();

            // Calculate offset for the next element
            totalOffset = (ending - outset) - contentLength;

            // Add to markable sheets
            MarkableSheet sheet =
                    new MarkableSheet(attributes, content, outset, ending, offset, contentLength);
            markableSheets.put(tag, sheet);

            // Toss the tag and keep content
            Matcher reMatcher = Markable.Patterns.XML.matcher(parcel);
            parcel = reMatcher.replaceFirst(content);
        }

        // Initialize spannable with the modified text
        Markable = new SpannableString(parcel);

        // Iterate through markable sheets
        for (MarkableSheet sheet : markableSheets.values()) {

            // Iterate through attributes
            for (MatchResult match : matches(Markable.Patterns.ATTRIBUTES, sheet.getAttributes())) {

                String attribute = match.group(1);
                String value = match.group(3);

                // Apply styles
                stylate(attribute,
                        value,
                        sheet.getOutset(),
                        sheet.getOffset(),
                        sheet.getContentLength());
            }
        }

        return Markable;
    }

ในที่สุดการจัดแต่งทรงผมนี่คือสไตเลอร์ที่เรียบง่ายมากที่ฉันสร้างขึ้นเพื่อคำตอบนี้:

public void stylate(String attribute, String value, int outset, int offset, int length) {

        // Correct position
        outset -= offset;
        length += outset;

        if (attribute.equals(Markable.Tags.TEXT_STYLE)) {

            if (value.contains(Markable.Tags.BOLD) && value.contains(Markable.Tags.ITALIC)) {

                Markable.setSpan(
                        new StyleSpan(Typeface.BOLD_ITALIC),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            else if (value.contains(Markable.Tags.BOLD)) {

                Markable.setSpan(
                        new StyleSpan(Typeface.BOLD),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            else if (value.contains(Markable.Tags.ITALIC)) {

                Markable.setSpan(
                        new StyleSpan(Typeface.ITALIC),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            if (value.contains(Markable.Tags.UNDERLINE)) {

                Markable.setSpan(
                        new UnderlineSpan(),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        if (attribute.equals(Markable.Tags.TEXT_COLOR)) {

            if (value.equals(Markable.Tags.ATTENTION)) {

                Markable.setSpan(
                        new ForegroundColorSpan(ContextCompat.getColor(
                                getContext(),
                                R.color.colorAttention)),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            else if (value.equals(Markable.Tags.INTERACTION)) {

                Markable.setSpan(
                        new ForegroundColorSpan(ContextCompat.getColor(
                                getContext(),
                                R.color.colorInteraction)),
                        outset,
                        length,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
    }

และนี่คือลักษณะของMarkableคลาสที่มีคำจำกัดความ:

public class Markable {

    public static class Patterns {

        public static final Pattern XML =
                Pattern.compile("<([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)(?:\\s+([^>]*))?>([^>][^<]*)</\\1\\s*>");
        public static final Pattern ATTRIBUTES =
                Pattern.compile("(\\S+)\\s*=\\s*(['\"])\\s*(.+?)\\s*\\2");
    }

    public static class Tags {

        public static final String MARKABLE = "markable";

        public static final String TEXT_STYLE = "textStyle";
        public static final String BOLD = "bold";
        public static final String ITALIC = "italic";
        public static final String UNDERLINE = "underline";

        public static final String TEXT_COLOR = "textColor";
        public static final String ATTENTION = "attention";
        public static final String INTERACTION = "interaction";
    }
}

สิ่งที่เราต้องการตอนนี้คือการอ้างอิงสตริงและโดยพื้นฐานแล้วมันควรมีลักษณะดังนี้:

<string name="markable_string">
    <![CDATA[Hello <markable textStyle=\"underline\" textColor=\"interaction\">world</markable>!]]>
</string>

อย่าลืมปิดแท็กด้วย a CDATA Sectionและ Escape "ด้วย\ด้วย

ฉันทำให้สิ่งนี้เป็นโซลูชันแบบแยกส่วนเพื่อประมวลผลส่วนต่างๆของข้อความด้วยวิธีต่างๆทั้งหมดโดยไม่จำเป็นต้องยัดโค้ดที่ไม่จำเป็นไว้ข้างหลัง


4

ฉันทำตามที่ andy boot บอก แต่ฉันก็มีช่วงที่คลิกได้เช่นกันและมันใช้ไม่ได้เพราะคำสั่งsetSpansถูกเรียก ดังนั้นคุณต้องเรียกใช้spannable.setSpan(clickableSpanand...ก่อนspannable.setSpan(new ForegroundColorSpan...เพื่อรับสีใน TextView


4

ฉันได้ทำฟังก์ชั่นเล็ก ๆ น้อย ๆ นี้เพียงแค่ส่งข้อความของคุณไปเป็นสีดัชนีเริ่มต้นและจุดสิ้นสุดของสิ่งที่คุณต้องการให้สีของข้อความนั้นและสีเอง

Kotlin

   private fun colorMyText(inputText:String,startIndex:Int,endIndex:Int,textColor:Int):Spannable{
            val outPutColoredText: Spannable = SpannableString(inputText)
            outPutColoredText.setSpan(
                ForegroundColorSpan(textColor), startIndex, endIndex,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            return outPutColoredText
        }

การใช้งาน

txt_comment.text = colorMyText("Comentario: ${item.comentario}",0,13,Color.BLACK)

2

ด้วยฟังก์ชั่นส่วนขยาย Kotlin ที่ใช้งานทั่วไปจะมีลักษณะดังนี้:

/**
 * Change the color of a part of the text contained in this textView
 *
 * @param subStringToColorize has to already be set in the textView's text
 * @param colorResId
 */
fun TextView.colorize(subStringToColorize: String, @ColorRes colorResId: Int) {

  val spannable: Spannable = SpannableString(text)

  val startIndex = text.indexOf(subStringToColorize, startIndex = 0, ignoreCase = false)
  val endIndex = startIndex + subStringToColorize.length

  val color: Int = ContextCompat.getColor(context, colorResId)

  if (startIndex != -1) {
      spannable.setSpan(ForegroundColorSpan(color),
          startIndex,
          endIndex,
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
      setText(spannable, TextView.BufferType.SPANNABLE)
   }
}

1

ใช้อักขระ Escape + Html.fromHtml ()

ป้อนคำอธิบายภาพที่นี่

วิธีการจัดเก็บ String ในโฟลเดอร์ทรัพยากรสตริง

<string name="textFromRes">
    &lt;font color="#FF0000">This is colored in red &lt;/font> This is not
</string>

จะแสดงใน TextView ได้อย่างไร?

String text = this.getResources().getString(R.string.textFromRes);
htmlText.setText(Html.fromHtml(text));

โบนัส:

สตริงในเอาต์พุตมีลักษณะดังนี้

<string name="textFromRes">
    &lt;font color="#FF0000">This is colored in red &lt;/font> This is not
    &lt;br /&gt;
    &lt;h1> This is h1 heading &lt;/h1>
    &lt;br /&gt;
    &lt;h3> This is h2 subheading&lt;/h3>
    &lt;br /&gt;
    &lt;b> This text is bold&lt;/b>
    &lt;br /&gt;
    &lt;i> This text is italic&lt;/i>
    &lt;br /&gt;
    Android users expect your app to look and behave in a way that is
    consistent with the platform. Not only should you follow material
    design guidelines for visual and navigation patterns,
    but you should also follow quality guidelines for compatibility,
    performance, security, and more.
    &lt;br /&gt;
    &lt;br /&gt;
    The following links provide everything you need to design a high quality Android app.
</string>

1

แรงบันดาลใจจากคำตอบของ Alejandro H. Cruz ข้างต้นดังกล่าวข้างต้น

ฟังก์ชั่นของเขาใช้ได้กับการจับคู่สตริงย่อยเดียวเท่านั้นฉันได้อัปเดตวิธีการของเขาเพื่อใช้ Regex และควรอัปเดตสีในการจับคู่ทั้งหมด:

fun TextView.colorizeAll(subStringToColorize: String, @ColorRes colorResId: Int) {

    val color: Int = ContextCompat.getColor(context, colorResId)

    val spannable: Spannable = SpannableString(text)

    val pattern = subStringToColorize.toRegex()

    val matches = pattern.findAll(text, 0)

    matches.forEach { match ->

        val startIndex = match.range.first

        val endIndex = match.range.last + match.range.step

        spannable.setSpan(ForegroundColorSpan(color),
                startIndex,
                endIndex,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        setText(spannable, TextView.BufferType.SPANNABLE)

    }
}

ใช้.toRegex(RegexOption.IGNORE_CASE)ถ้าคุณต้องการจับคู่สตริงโดยไม่คำนึงถึงกรณี
JustinMorris

0

ฉันสร้างวิธีการช่วยเหลือเล็ก ๆ น้อย ๆ นี้ที่สามารถเรียกได้จากไฟล์ TextView :

fun TextView.attributedString(
    forText: String,
    foregroundColor: Int? = null,
    style: StyleSpan? = null
) {
  val spannable: Spannable = SpannableString(text)

  // check if the text we're highlighting is empty to abort
  if (forText.isEmpty()) {
    return
  }

  // compute the start and end indices from the text
  val startIdx = text.indexOf(forText)
  val endIdx = startIdx + forText.length

  // if the indices are out of bounds, abort as well
  if (startIdx < 0 || endIdx > text.length) {
    return
  }

  // check if we can apply the foreground color
  foregroundColor?.let {
    spannable.setSpan(
        ForegroundColorSpan(it),
        startIdx,
        endIdx,
        Spannable.SPAN_INCLUSIVE_EXCLUSIVE
    )
  }

  // check if we have a stylespan
  style?.let {
    spannable.setSpan(
        style,
        startIdx,
        endIdx,
        Spannable.SPAN_INCLUSIVE_EXCLUSIVE
    )
  }

  // apply it
  text = spannable
}

วิธีใช้:

plateText.text = "Hello world!"

// This will color the part "world" to whatever color you have defined
// And make the word **bold**.
plateText.attributedString(
   "world",
   getColor(R.color.colorMatchingText, null),
   StyleSpan(Typeface.BOLD)
)

ทดสอบกับ API 29 ไชโย!


0
SpannableStringBuilder builder = new SpannableStringBuilder();

    String the = "The ";
    SpannableString theSpannable= new SpannableString(the);
    builder.append(theSpannable);
    String author = "author ";
    SpannableString authorSpannable= new SpannableString(author);
    authorSpannable.setSpan(new RelativeSizeSpan(1.2f), 0,authorSpannable.length(), 0); // set size
    authorSpannable.setSpan(new ForegroundColorSpan(Color.BLACK), 0, authorSpannable.length(), 0);
    builder.append(authorSpannable);
    String has = "has ";
    SpannableString hasSpannable= new SpannableString(has);
    builder.append(hasSpannable);

    String approved = "approved ";
    SpannableString approvedSpannable= new SpannableString(approved);
    approvedSpannable.setSpan(new RelativeSizeSpan(1.2f), 0,approvedSpannable.length(), 0); // set size
    StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
    approvedSpannable.setSpan(boldSpan, 0, approvedSpannable.length() + 0, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    approvedSpannable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.CLR_PRESSED_SAVED)), 0,
            approvedSpannable.length(), 0);
    builder.append(approvedSpannable);

    String white = "your access to this share. Do you want re-access now?";
    SpannableString whiteSpannable= new SpannableString(white);
    builder.append(whiteSpannable);
    _AccessStatusText.setText(builder, TextView.BufferType.SPANNABLE);

-5

วิธีหนึ่งคือแยกออกmyTextViewเป็นสองสามรายการTextViewsซึ่งหนึ่งในนั้นใช้สำหรับรหัสโทรศัพท์เท่านั้น จากนั้นการควบคุมสีเฉพาะนี้TextViewก็ค่อนข้างตรงไปตรงมา


7
ไม่ปวดตูด การใช้ spannable เป็นวิธีที่ถูกต้อง
Marc DiMillo

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