programing

TextView 내에 여러 스타일을 사용할 수 있습니까?

stoneblock 2023. 6. 3. 08:08

TextView 내에 여러 스타일을 사용할 수 있습니까?

TextView 내의 여러 텍스트에 대해 여러 스타일을 설정할 수 있습니까?

예를 들어, 저는 다음과 같이 텍스트를 설정하고 있습니다.

tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3);

텍스트 요소마다 다른 스타일을 가질 수 있습니까?예: line1 bold, word1 이탤릭체 등

Android에서 개발자 가이드의 일반 작업작업 방법에는 텍스트 부분 선택, 강조 표시 또는 스타일 지정이 포함됩니다.

// Get our EditText object.
EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.
vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:
// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
// to force it to use Spannable storage so styles can be attached.
// Or we could specify that in the XML.

// Get the EditText's internal text storage
Spannable str = vw.getText();

// Create our span sections, and assign a format to each.
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

하지만 그것은 텍스트 안에 명시적인 위치 번호를 사용합니다.더 깨끗한 방법이 있을까요?

만약을 위해, 누구나 이것을 어떻게 하는지 궁금해 할 경우, 한 가지 방법이 있습니다: (마크에게 다시 감사드립니다!)

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

이 방법으로 지원되는 비공식 태그 목록은 다음 링크 또는 다음 질문을 참조하십시오.Android TextView에서 지원하는 HTML 태그는 무엇입니까?

ㅠㅠHtml.fromHtml() 예 HTML 를 사용합니다. 예:

Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff");
textView.setText(text);

약간 주제에서 벗어났지만, 저는 이것이 여기서 언급하기에는 너무 유용하다는 것을 알았습니다.

string.xml 리소스에서 HTML 텍스트를 읽어 현지화를 쉽게 하려면 어떻게 해야 합니까?CDATA를 사용하면 다음과 같은 이점이 있습니다.

<string name="my_text">
  <![CDATA[
    <b>Autor:</b> Mr Nice Guy<br/>
    <b>Contact:</b> myemail@grail.com<br/>
    <i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i>
  ]]>
</string> 

이제 Java 코드를 사용하여 다음과 같이 활용할 수 있습니다.

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setText(Html.fromHtml(getString(R.string.my_text))); 

저는 이것이 효과가 있을 것이라고 예상하지 못했습니다.하지만 그것은 그랬다.

여러분 중 일부에게 유용하기를 바랍니다!

HTML을 사용하고 싶지 않다면 styles.xml을 만들어 다음과 같이 사용할 수 있습니다.

TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);

text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

tv.setText(text, TextView.BufferType.SPANNABLE);

사용하기에 더 가벼운 무게입니다.SpannableStringmarkup.tml 사용할 수 .시각적인 예를 보는 데 도움이 되므로 여기 보충적인 답변이 있습니다.

여기에 이미지 설명 입력

이은싱다니입입니다.TextView.

// set the text
SpannableString s1 = new SpannableString("bold\n");
SpannableString s2 = new SpannableString("italic\n");
SpannableString s3 = new SpannableString("foreground color\n");
SpannableString s4 = new SpannableString("background color\n");
SpannableString s5 = new SpannableString("underline\n");
SpannableString s6 = new SpannableString("strikethrough\n");
SpannableString s7 = new SpannableString("bigger\n");
SpannableString s8 = new SpannableString("smaller\n");
SpannableString s9 = new SpannableString("font\n");
SpannableString s10 = new SpannableString("URL span\n");
SpannableString s11 = new SpannableString("clickable span\n");
SpannableString s12 = new SpannableString("overlapping spans\n");

// set the style
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag);
s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag);
s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag);
s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag);
s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag);
s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag);
s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag);
s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag);
s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag);
s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag);
s11.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show();
    }
}, 0, s11.length(), flag);
s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag);
s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag);
s12.setSpan(new UnderlineSpan(), 4, 11, flag);

// build the string
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(s1);
builder.append(s2);
builder.append(s3);
builder.append(s4);
builder.append(s5);
builder.append(s6);
builder.append(s7);
builder.append(s8);
builder.append(s9);
builder.append(s10);
builder.append(s11);
builder.append(s12);

// set the text view with the styled text
textView.setText(builder);
// enables clicking on spans for clickable span and url span
textView.setMovementMethod(LinkMovementMethod.getInstance());

추가 연구

이 예시는 원래 여기서 영감을 받았습니다.

지원되는 태그 목록은 다음과 같습니다.

문자열 리소스를 사용하는 경우 HTML 표기법을 사용하여 굵게 또는 기울임꼴과 같은 간단한 스타일을 추가할 수 있습니다.는 다음과 같습니다.B(굵은 글씨),I (이탤릭체),U (으), (계속)TT (monospace),BIG,SMALL,SUP (원고),SUB (으), (으), 고.STRIKE(스트라이크 스루). 서래들, 면를예에서,res/values/strings.xml다음과 같이 선언할 수 있습니다.

<resource>
    <string id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

(http://developer.android.com/guide/faq/commontasks.html#selectingtext 에서 - 웹 보관 링크,<resource>오타는 원본입니다!)

또한 다음과 같은 것을 보여줍니다.Html.fromHtml단순한 경우에는 실제로 필요하지 않습니다.

저도 같은 문제에 부딪혔어요.저는 Html에서 사용할 수 있지만, 저는 지금 웹이 아닌 안드로이드이기 때문에 이것을 사용해 보기로 결정했습니다.하지만 이것을 현지화해야 하기 때문에 스트링 교체 개념을 사용하여 시도했습니다.텍스트 보기의 스타일을 메인 스타일로 설정한 다음 다른 조각을 포맷합니다.

저는 이것이 다른 사람들이 같은 일을 하는 데 도움이 되기를 바랍니다. 저는 이것이 프레임워크에서 왜 더 쉽지 않은지 모르겠습니다.

내 줄은 다음과 같습니다.


<string name="my_text">{0} You will need a {1} to complete this assembly</string>
<string name="text_sub0">1:</string>
<string name="text_sub1">screwdriver, hammer, and measuring tape</string>

다음은 스타일입니다.


<style name="MainStyle">
    <item name="android:textSize">@dimen/regular_text</item>
    <item name="android:textColor">@color/regular_text</item>
</style>
<style name="style0">
    <item name="android:textSize">@dimen/paragraph_bullet</item>
    <item name="android:textColor">@color/standout_text</item>
    <item name="android:textStyle">bold</item>
</style>
<style name="style1">
    <item name="android:textColor">@color/standout_light_text</item>
    <item name="android:textStyle">italic</item>
</style>

다음은 내 formatStyles 메서드를 호출하는 내 코드입니다.


SpannableString formattedSpan = formatStyles(getString(R.string.my_text), getString(R.string.text_sub0), R.style.style0, getString(R.string.main_text_sub1), R.style.style1);
textView.setText(formattedSpan, TextView.BufferType.SPANNABLE);

포맷 방법:


private SpannableString formatStyles(String value, String sub0, int style0, String sub1, int style1)
{
    String tag0 = "{0}";
    int startLocation0 = value.indexOf(tag0);
    value = value.replace(tag0, sub0);

    String tag1 = "{1}";
    int startLocation1 = value.indexOf(tag1);
    if (sub1 != null && !sub1.equals(""))
    {
        value = value.replace(tag1, sub1);
    }

    SpannableString styledText = new SpannableString(value);
    styledText.setSpan(new TextAppearanceSpan(getActivity(), style0), startLocation0, startLocation0 + sub0.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    if (sub1 != null && !sub1.equals(""))
    {
        styledText.setSpan(new TextAppearanceSpan(getActivity(), style1), startLocation1, startLocation1 + sub1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return styledText;
}

이제더더.<b>요소가 더 이상 사용되지 않습니다. <strong>를 렌링더됨으로 렌더링합니다.<b>,그리고.<em>를 렌링더됨으로 렌더링합니다.<i>.

tv.setText(Html.fromHtml("<strong>bold</strong> and <em>italic</em> "));

이것은 나에게 잘 작동합니다.

예, 다음을 사용하여 가능합니다.SpannedString코틀린을 사용하는 경우에는 사용하기가 훨씬 더 쉬워집니다.core-ktx다음을 수행하기 위한 DSL(도메인 특정 언어)을 제공합니다.

    val string: SpannedString = buildSpannedString {
        bold {
            append("1111")
        }
        append("Devansh")     
    }

기타 옵션은 다음과 같습니다.

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

마지막으로 다음을 수행할 수 있습니다.

textView.text = string

HTML Builder를 사용하여 쉽게 수행할 수 있는 방법은 다음과 같습니다.

    myTextView.setText(new HtmlBuilder().
                    open(HtmlBuilder.Type.BOLD).
                    append("Some bold text ").
                    close(HtmlBuilder.Type.BOLD).
                    open(HtmlBuilder.Type.ITALIC).
                    append("Some italic text").
                    close(HtmlBuilder.Type.ITALIC).
                    build()
    );

결과:

굵게 표시된 텍스트 일부 기울임꼴 텍스트

스타일링된 텍스트를 xml로 추가하려면 TextView를 확장하는 사용자 정의 뷰를 만들고 setText()를 재정의할 수 있습니다.

public class HTMLStyledTextView extends TextView
{
    public HTMLStyledTextView(Context context) {
        super(context);
    }

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

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

    @Override
    public void setText(CharSequence text, BufferType type)
    {
       super.setText(Html.fromHtml(text.toString()), type);
    }
}

.PACKAGE_NAME패키지 이름 포함):

<PACKAGE_NAME.HTMLStyledTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="<![CDATA[
        <b>Bolded Text:</b> Non-Bolded Text
    ]]>"
/>

설명한 바와 같이, 사용TextView.setText(Html.fromHtml(String))

HTML 형식 문자열에 다음 태그를 사용합니다.

<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>

http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html

나도

Kotlin과 Anko와 함께 아름다운 마크업을 하는 것은 어떻습니까?

import org.jetbrains.anko.*
override fun onCreate(savedInstanceState: Bundle?) {
    title = "Created with Beautiful Markup"
    super.onCreate(savedInstanceState)

    verticalLayout {
        editText {
            hint = buildSpanned {
                append("Italic, ", Italic)
                append("highlighted", backgroundColor(0xFFFFFF00.toInt()))
                append(", Bold", Bold)
            }
        }
    }
}

Beautiful Markup으로 작성

스판을 사용하면 스판 가능 문자열을 쉽게 사용할 수 있습니다.

Spanny spanny = new Spanny("Underline text", new UnderlineSpan())
                .append("\nRed text", new ForegroundColorSpan(Color.RED))
                .append("\nPlain text");
textView.setText(spanny)

실제로 Html 개체를 제외하고 스패너블 유형 클래스를 사용할 수도 있습니다.텍스트 모양 범위 또는 글꼴 범위 및 스패너블 문자열이 함께 표시됩니다.HTML 클래스도 이러한 메커니즘을 사용합니다.그러나 스패너블 유형의 클래스를 사용하면 더 많은 자유를 얻을 수 있습니다.

String's length() 메서드를 활용하는 것만큼 간단할 수 있습니다.

  1. Strings XML 파일의 텍스트 문자열을 필요한 만큼의 하위 문자열(Android 관점에서 별도의 문자열)로 분할하면 str1, str2, str3과 같은 스타일이 될 수 있습니다(예: 함께 결합할 때 사용하는 전체 단일 문자열).

  2. 그런 다음 코드와 함께 제시한 것처럼 "스팬" 방법을 따르기만 하면 됩니다. 단 하나의 문자열 대신 모든 하위 문자열을 결합하여 각각 다른 사용자 지정 스타일을 가진 단일 문자열로 만듭니다.

숫자는 직접적이지는 않지만 여전히 사용하고 있습니다. 이제 코드에서처럼 하드코딩된 형태는 아니지만 결합된 길이() 방법으로 대체되고 있습니다(변경 사항을 제거하기 위해 절대 숫자 대신 str.length() 앞에 있는 두 개의 별에 접미사를 붙입니다).

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

첫 번째 문자열 크기에 대해서는 str.length () + 1, 두 번째 문자열 크기에 대해서는 str.length () + str2.length () 등으로, 예를 들어 0,7 또는 8,19 등이 아닌 모든 하위 문자열에 대해서도 마찬가지입니다.

보조 스패너블 클래스를 Android 문자열 리소스로 사용하면 웹 페이지 하단에서 공유할 수 있습니다.다음을 생성하여 접근할 수 있습니다.CharSquences그들에게 스타일을 주는 것.

하지만 그들이 우리에게 제공하는 예시는 단지 굵은 글씨, 이탤릭체, 심지어 색을 칠한 글자를 위한 것입니다.여러 가지 스타일로 포장을 해야 했습니다.CharSequence그들을 곤경에 빠뜨리기 위해.TextView그래서 그 수업에 (내가 이름 지었습니다.CharSequenceStyles) 방금 이 기능을 추가했습니다.

public static CharSequence applyGroup(LinkedList<CharSequence> content){
    SpannableStringBuilder text = new SpannableStringBuilder();
    for (CharSequence item : content) {
        text.append(item);
    }
    return text;
}

그리고 이 관점에서 저는 이것을 추가했습니다.

            message.push(postMessageText);
            message.push(limitDebtAmount);
            message.push(pretMessageText);
            TextView.setText(CharSequenceStyles.applyGroup(message));

이것이 당신에게 도움이 되길 바랍니다!

Jon이 말했듯이, 이것은 나에게 최고의 솔루션이며 당신은 런타임에 어떤 텍스트도 설정할 필요가 없고 오직 이 사용자 정의 클래스 HtmlTextView만 사용합니다.

public class HtmlTextView extends TextView {

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

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

  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) 
  {
      super(context, attrs, defStyleAttr);
  }

  @TargetApi(21)
  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  @Override
  public void setText(CharSequence s,BufferType b){
      super.setText(Html.fromHtml(s.toString()),b);
  }

}

이제 XML에만 입력합니다.

<com.fitc.views.HtmlTextView
    android:id="@+id/html_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/example_html" />

HTML 문자열을 사용하여

<string name="example_html">
<![CDATA[
<b>Author:</b> Mr Donuthead<br/>
<b>Contact:</b> me@donut.com<br/>
<i>Donuts for life </i>
]]>

코틀린에서 가장 깨끗한 방법은 스판을 사용하는 것입니다.

val myTitleText = "Hello World"

val spannable = SpannableString(myTitleText)
spannable.setSpan(
    TextAppearanceSpan(context, R.style.myFontMedium),
    0,
    4,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
tvMytitle.text = spannable

보낸 사람: Hello Word

받는 사람: 헬로 월드

사용.SpannableString그것을 달성하는 좋은 방법입니다.

저는 적용하기 쉽도록 몇 가지 기능을 사용합니다. 각 기능에 대한 아이디어를 먼저 설명한 다음 코드를 보여드리겠습니다.

  1. String.getAllIndexOf(pattern: String)문자열에서 패턴을 검색하고 패턴이 시작되는 위치의 인덱스 목록을 반환합니다.예: 문자열이 지정"abcdefabc"그리고 나는 통과하는 방법을 부릅니다."abc"검색된 패턴으로 메소드는 목록을 반환해야 합니다.listOf(0, 6)
  2. 는 다음을 수신하는 클래스입니다.pattern및 스타일 목록(다른 스타일을 동일한 패턴에 순차적으로 적용하려는 경우)
  3. SpannableString.applyStyle(context: Context, vararg patternAndStyles: PatternAndStyles)지정된 패턴에 스타일을 적용합니다.

자, 코드상:

  1. 모든 인덱스 가져오기

    fun String.getAllIndexOf(pattern: String): List<Int> {
        val allRecordsOfText = mutableListOf<Int>()
    
        var index = 0
        while(index >= 0) {
            val newStart = if (allRecordsOfText.isEmpty()) {
                0
            } else {
                allRecordsOfText.last() + pattern.length
            }
            index = this.subSequence(newStart, this.length).indexOf(pattern)
    
            if (index >= 0) {
                allRecordsOfText.add(newStart + index)
            }
        }
    
        return allRecordsOfText.toList()
    }
    
  2. 패턴 및 스타일을 수신할 클래스

    @Parcelize
    class PatternAndStyles(
        val pattern: String,
        val styles: List<Int>
    ) : Parcelable
    
  3. 스타일 적용

    fun SpannableString.applyStyle(context: Context, vararg patternAndStyles: PatternAndStyles) {
        for (patternStyle in patternAndStyles.toList()) {
    
            this.toString().getAllIndexOf(patternStyle.pattern).forEachIndexed { index, start ->
                val end = start + patternStyle.pattern.length
                val styleIndex = if (patternStyle.styles.size > index) index else patternStyle.styles.size - 1
    
                this.setSpan(
                    TextAppearanceSpan(context, patternStyle.styles[styleIndex]),
                    start,
                    end,
                    SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
        }
    }
    
  4. 최종적으로 사용하는 방법

    val stringToApplyStyle = "abc def abc def"
    val text = SpannableString(stringToApplyStyle)
    text.applyStyle(
        this.applicationContext,
        PatternAndStyles("abc", listOf(R.style.Style1, R.style.Style2)),
        PatternAndStyles("def", listOf(R.style.Style3))
    )
    
  5. 출력:
    텍스트에 적용된 스타일

패턴에 스타일로 전달되면서"abc"둘 다 사용되었지만 패턴상으로는"def"목록에 주어진 마지막 스타일을 재사용한 두 번째 레코드

언급URL : https://stackoverflow.com/questions/1529068/is-it-possible-to-have-multiple-styles-inside-a-textview