web-dev-qa-db-ja.com

TextView内に複数のスタイルを含むことは可能ですか?

TextView内のさまざまなテキストに複数のスタイルを設定することは可能ですか?

たとえば、テキストを次のように設定しています。

tv.setText(line1 + "\n" + line2 + "\n" + Word1 + "\t" + Word2 + "\t" + Word3);

各テキスト要素に異なるスタイルを設定することは可能ですか?たとえば、行1の太字、Word1の斜体など.

開発者ガイドの 一般的な作業とAndroidでの操作方法 includes テキストの一部を選択、強調表示、またはスタイル設定する

// 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);

しかしそれはテキスト内の明示的な位置番号を使用します。これを行うためのよりクリーンな方法はありますか?

520
Legend

念のために、誰もがこれを行う方法を疑問に思っています、ここに1つの方法があります:(Markにまた感謝します!)

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

このメソッドでサポートされているタグの非公式リストについては、 このリンク またはこの質問を参照してください。 Android TextViewでサポートされているHTMLタグはどれですか。

683
Legend

Html.fromHtml()を試して、テキストを太字のイタリック体のHTMLタグでマークしてください。

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

少し話題から外れていますが、ここでは言及しないでおくとあまりにも有用です。

Htmlのテキストを string.xml そのため、ローカライズが容易になります。 CDATA これを可能にする:

<string name="my_text">
  <![CDATA[
    <b>Autor:</b> Mr Nice Guy<br/>
    <b>Contact:</b> [email protected]<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))); 

私はこれがうまくいくとは思っていませんでした。しかしそうでした。

それがあなたの何人かに役立つことを願っています!

181
Ben

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);
113
Kent Andersen

Htmlマークアップの代わりにSpannableStringを使用する方がより軽量です。それは私が視覚的な例を見るのを助けます。

enter image description here

これは単一の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());

さらなる研究

この例はもともと here からヒントを得たものです。

45
Suragch

サポートされているタグのリストは次のとおりです。

文字列リソースを使用する場合は、太字や斜体などの簡単なスタイルをHTML表記を使用して追加できます。現在サポートされているタグは次のとおりです。B(太字)、I(斜体)、U(下線)、TT(固定幅)、BIGSMALLSUP(上付き文字)、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から - Web Archiveリンク、<resource>タイプミスはオリジナルです!)

また、Html.fromHtmlは単純なケースでは本当に必要ではないことも示しています。

39
Jon

私は同じ問題に遭遇しました。私はfromHtmlを使うことができましたが、私は今Androidであり、webではないので、これを試すことにしました。私はこれをローカライズする必要がありますが、文字列置換の概念を使用してショットを付けました。 TextViewのスタイルをメインスタイルに設定してから、他のpeicesをフォーマットします。

これが他の人が同じことをやろうとしているのを助けてくれることを願っています - なぜこれがフレームワークでは簡単ではないのかわかりません。

私の文字列は次のようになります。


<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;
}
16
farcrats

<b>要素は非推奨になりました。 <strong><b>としてレンダリングされ、<em><i>としてレンダリングされます。

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

これは私にとってはうまくいく

12
Sandy09

HTMLBuilder を使用してこれを簡単に行う方法は次のとおりです。

    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()
    );

結果:

太字のテキスト 斜体のテキスト

6
Ilya Gazman

述べたように、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

6
Andrew Gallasch

スタイル付きテキストを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
    ]]>"
/>
6
bcorso

私も

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)
            }
        }
    }
}

Created with Beautiful Markup

2
Himanshu

はい、SpannedStringを使用して可能です。 Kotlinを使用している場合は、core-ktxを使用することでさらに簡単になります。これを行うために domain-specific-language(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
1
Devansh Maurya

Spanny SpannableStringを使いやすくする。

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

Android String Resourcesとして/ - 補助Spannableクラスを使用する Webページの下部に共有します。あなたはCharSquencesを作成し、それらにスタイルを与えることによってこれに取り組むことができます。

しかし、彼らが私たちに与える例では、単に太字、斜体、さらにはテキストの色付けのためのものです。私はそれらをCharSequenceに設定するためにaTextViewでいくつかのスタイルをラップする必要がありました。だからそのクラス(私はそれを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));

これがお役に立てば幸いです。

0
MontDeska

実際には、Htmlオブジェクトを除いて、Spannable型クラスを使うこともできます。 TextAppearanceSpanまたはTypefaceSpanとSpannableStringを組み合わせます。 HTMLクラスもこれらのメカニズムを使用します。しかし、Spannable型クラスを使えば、もっと自由になります。

0
Clock ZHONG

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> [email protected]<br/>
<i>Donuts for life </i>
]]>
0
AWolfsdorf

Stringのlength()メソッドを利用するのと同じくらい簡単かもしれません:

  1. Strings XMLファイルのテキスト文字列を、さまざまなスタイルが必要な数のサブ文字列(Androidの観点から見た場合は別の文字列)に分割するので、次のようになります。 str1、str2、str3 (あなたの場合のように、それは一緒に結合されたときあなたが使用する単一の文字列全体です。

  2. そして、あなたがあなたのコードで提示したのと同じように、 "Span"メソッドに従ってください - しかし、単一の文字列の代わりに、それらをマージするすべての部分文字列を組み合わせます。

それでも直接使用するのではなく、番号を使用します。コードのようにハードコードされた形式にはなっていませんが、それらは結合されたlength()メソッドに置き換えられています。絶対値の代わりにlength()を使って変更を無効にします。

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

最初の文字列サイズの場合は、 str.length()+ 1、2番目の文字列サイズの場合は、str.length()+ str2.length() というようになります。 0、7、8、19など.

0
forsberg