整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Android TextView實(shí)現(xiàn)富文本

          Android TextView實(shí)現(xiàn)富文本

          extView富文本顯示主要有兩種方式,一個(gè)是使用SpannableString類,另一種是直接將富文本寫成HTML形式。

          SpannableString

          SpannableString是Android內(nèi)置的專門處理富文本的類,基本涵蓋了你能想到的所有富文本表示,字體、顏色、圖片、點(diǎn)擊事件等

          //設(shè)置Hello World前三個(gè)字符為紅色,背景為藍(lán)色
          SpannableString textSpanned1=new SpannableString("Hello World");
          textSpanned1.setSpan(new ForegroundColorSpan(Color.RED),
                  0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          textSpanned1.setSpan(new BackgroundColorSpan(Color.BLUE),
                  0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          text1.setText(textSpanned1);
          
          //設(shè)置Hello World前三個(gè)字符字體為斜體
          SpannableString textSpanned2=new SpannableString("Hello World");
          textSpanned2.setSpan(new StyleSpan(Typeface.ITALIC),
                  0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          text2.setText(textSpanned2);
          
          //設(shè)置Hello World前三個(gè)字符有下劃線
          SpannableString textSpanned3=new SpannableString("Hello World");
          textSpanned3.setSpan(new UnderlineSpan(),
                  0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          text3.setText(textSpanned3);
          
          //設(shè)置Hello World前三個(gè)字符有點(diǎn)擊事件
          SpannableStringBuilder textSpanned4=new SpannableStringBuilder("Hello World");
          ClickableSpan clickableSpan=new ClickableSpan() {
              @Override
              public void onClick(View view) {
                  Toast.makeText(MainActivity.this, "Hello World", Toast.LENGTH_SHORT).show();
              }
          };
          textSpanned4.setSpan(clickableSpan,
                  0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          //注意:此時(shí)必須加這一句,不然點(diǎn)擊事件不會(huì)生效
          text4.setMovementMethod(LinkMovementMethod.getInstance());
          text4.setText(textSpanned4);

          setSpan()

          void setSpan (Object what, int start, int end, int flags)

          參數(shù)

          說明

          what

          樣式

          start

          樣式開始的字符索引

          end

          樣式結(jié)束的字符索引

          flags

          新插入字符的設(shè)置

          flags:

          取值

          說明

          Spanned.SPAN_EXCLUSIVE_EXCLUSIVE

          前后都不包括

          Spanned.SPAN_EXCLUSIVE_INCLUSIVE

          前面不包括,后面包括

          Spanned.SPAN_INCLUSIVE_EXCLUSIVE

          前面包括,后面不包括

          Spanned.SPAN_INCLUSIVE_INCLUSIVE

          前后都包括

          這個(gè)flags可能有人不懂,它表示了這個(gè)樣式是否作用在本字符串之前或之后插入的其他字符串上

          SpannableStringBuilder textSpannedBuilder1=new SpannableStringBuilder();
          SpannableString textSpanned11=new SpannableString("Hello");
          textSpanned11.setSpan(new BackgroundColorSpan(Color.BLUE), 0, textSpanned11.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          SpannableString textSpanned12=new SpannableString("World");
          text1.setText(textSpannedBuilder1.append(textSpanned11).append(textSpanned12));
          
          SpannableStringBuilder textSpannedBuilder2=new SpannableStringBuilder();
          SpannableString textSpanned21=new SpannableString("Hello");
          textSpanned21.setSpan(new BackgroundColorSpan(Color.BLUE), 0, textSpanned21.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
          SpannableString textSpanned22=new SpannableString("World");
          text2.setText(textSpannedBuilder2.append(textSpanned21).append(textSpanned22));
          
          SpannableStringBuilder textSpannedBuilder3=new SpannableStringBuilder();
          SpannableString textSpanned31=new SpannableString("Hello");
          textSpanned31.setSpan(new BackgroundColorSpan(Color.BLUE), 0, textSpanned21.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
          SpannableString textSpanned32=new SpannableString("World");
          textSpanned32.setSpan(new BackgroundColorSpan(Color.GREEN), 0, 3, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
          text3.setText(textSpannedBuilder3.append(textSpanned31).append(textSpanned32));

          text1里,"Hello"的flags是SPAN_EXCLUSIVE_EXCLUSIVE,在它之后插入的"World"顯示正常,無(wú)背景。

        1. text2里,"Hello"的flags是SPAN_EXCLUSIVE_INCLUSIVE,它之后插入的"World"的背景變?yōu)樗{(lán)色。
        2. 需要注意的是text3,這里的"Hello"與text2相同,而"World"的一部分字符設(shè)置為綠色,顯然這部分字符顯示的是綠色,這說明雖然設(shè)置了SPAN_EXCLUSIVE_INCLUSIVE屬性,但只要后面的字符串設(shè)置了同類的樣式,還是覆蓋掉flags屬性。
        3. HTML

          接下來(lái)介紹HTML的用法,其實(shí)HTML使用起來(lái)要比SpannableString簡(jiǎn)潔,我們只需要按照平時(shí)寫HTML的習(xí)慣,將需要顯示的富文本加上各種標(biāo)簽,就可以顯示在TextView上了,下面我們看一下例子:

          String htmlText1="<b>Hello World</b>";
          text1.setText(Html.fromHtml(htmlText1));
          
          String htmlText2="<font color='#ff0000'>Hello World</font>";
          text2.setText(Html.fromHtml(htmlText2));
          
          String htmlText3="<i><a href='https://gavinli369.github.io/'>我的博客</a></i>";
          text3.setMovementMethod(LinkMovementMethod.getInstance());
          text3.setText(Html.fromHtml(htmlText3));

          TextView支持的HTML標(biāo)簽

          標(biāo)簽

          說明

          font

          設(shè)置字體和顏色

          big

          大號(hào)字體

          small

          小號(hào)字體

          i

          斜體

          b

          粗體

          tt

          等寬字體

          br

          換行(行與行之間沒有空行)

          p

          換行(行與行之間有空行)

          a

          鏈接

          img

          圖像

          ndroid 中的 TextView 組件常用于顯示文本內(nèi)容,其實(shí)它也可以顯示 HTML 的內(nèi)容。簡(jiǎn)單來(lái)講,這就需要先把 HTML 的內(nèi)容以字符串的形式獲取后,經(jīng)過 android.text.Html.fromHtml()轉(zhuǎn)化成 Spanned 的格式,然后將其傳遞到 TextView 的 setText()方法中,這樣就可以在 TextView 中顯示 HTML 頁(yè)面的內(nèi)容了。需要注意的是,并不是所有的 HTML 標(biāo)簽在 TextView 中都是支持的,且官方文檔并沒有明確的說明支持 HTML 標(biāo)簽列表,通過查看 Android 源代碼,可以得到簡(jiǎn)單的支持列表。

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

          下面的示例來(lái)介紹如何在 TextView 中顯示一段 HTML 內(nèi)容,要顯示的這段 HTML 內(nèi)容即包含超鏈接內(nèi)容,也包含有圖片。
          在 TextView 中顯示 HTML 內(nèi)容

          顯示的過程中最主要的過程就是調(diào)用 Android.text.Html 類提供的 fromHtml()方法,將一段 HTML 內(nèi)容轉(zhuǎn)化為 Spanned 對(duì)象。

          Android.text.Html 類提供的 fromHtml()方法使用如下清單 4
          fromHtml()方法定義

          public static Spanned fromHtml(String source, ImageGetter imageGetter,
              TagHandler tagHandler) {
                  ……
          HtmlToSpannedConverter converter=new HtmlToSpannedConverter(source, imageGetter, tagHandler,  parser);
          return converter.convert();
          }
          1234567

          source,就是包含 HTML 內(nèi)容的字符串。而 Html.ImageGetter 和 Html.TagHandler 是兩個(gè)接口,提供給開發(fā)者繼承使用。
          imageGetter, 如果要顯示圖片是需要被繼承的,重寫 getDrawable(String source)方法,用于獲取 HTML 里面的圖片來(lái)顯示在 TextView 中。
          tagHandler,其作用是把 HTML 帶標(biāo)記的文本內(nèi)容字符串轉(zhuǎn)化成可以顯示效果的的 Spanned 字符串 。由于并非所有的 HTML 標(biāo)簽都可以轉(zhuǎn)化,所以在使用時(shí),用戶需要自己添加一些必要的標(biāo)簽和處理方法時(shí)才會(huì)繼承使用的。

          在本例中使用 fromHtml()方法之前,要準(zhǔn)備好該方法要用的三個(gè)參數(shù)內(nèi)容,首先將 HTML 字符串內(nèi)容準(zhǔn)備好,在項(xiàng)目中需要?jiǎng)?chuàng)建兩個(gè)類 MImageGetter 和 MTagHandler 分別繼承于 ImageGetter 和 TagHandler,分別用戶圖片的獲取,和特殊標(biāo)簽的支持。
          MImageGetter

          繼承于 ImageGetter,重寫 getDrawable (String source) 方法中從 assets 路徑下取出的圖片流(這里當(dāng)然也可以通過網(wǎng)絡(luò)操作來(lái)完成圖片流的獲取),最后獲得可供顯示的圖片對(duì)象,例如 Drawable 對(duì)像。由于 Android 設(shè)備的異構(gòu)性,為了有更好的顯示效果,通常需要獲取屏幕大小,然后調(diào)用 drawable.setBounds () 還可以重新設(shè)置圖片的大小, 最后返回合適大小的圖片 Drawable 對(duì)象。 由此 Spanned 中的 ImageSpan 就獲得了圖像被顯示在 TextView 中對(duì)應(yīng)位置了。

          TypedValue typedValue=new TypedValue();
          typedValue.density=TypedValue.DENSITY_DEFAULT;
          drawable=Drawable.createFromResourceStream(null, typedValue, is, "src");
          DisplayMetrics dm=c.getResources().getDisplayMetrics();  
          int dwidth=dm.widthPixels-10;//padding left + padding right
          float dheight=(float)drawable.getIntrinsicHeight()*(float)dwidth/(float)drawable.getIntrinsicWidth();
          int dh=(int)(dheight+0.5);
          int wid=dwidth;
          int hei=dh;
          drawable.setBounds(0, 0, wid, hei);DisplayMetrics dm=c.getResources().getDisplayMetrics();
          12345678910

          MTagHandler

          繼承于 TagHandler,重寫了 handleTag()方法,為的是支持部分標(biāo)簽,這四個(gè)標(biāo)簽是在 formHtml()方法中本身是不支持。如果開發(fā)者認(rèn)為安卓 TagHandler 提供的默認(rèn)標(biāo)簽解析已經(jīng)夠用,直接在 fromHtml()方法中第三個(gè)參數(shù)的地方填寫 null 既可。
          重寫 handleTag()方法

          public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
          if (tag.equals("ul") || tag.equals("ol") || tag.equals("dd")) {
              if (opening) {
              mListParents.add(tag);
              } else mListParents.remove(tag);
          } else if (tag.equals("li") && !opening) {
               handleListTag(output);
          }
          }
          private void handleListTag(Editable output) {
          ……
           }
          123456789101112

          最后,在完成了 MImageGetter、MTagHandler 以后,就可以通過 formHtml()方法將 HTML 內(nèi)容轉(zhuǎn)化為可供顯示的 SpannableString,將 SpannableString 通過 setText 方法放入 TextView 中,就可以顯示圖文并茂的內(nèi)容了。

          progressBar.setVisibility(View.GONE);
          text.setText(Html.fromHtml(htmlCont, new MImageGetter(text,MainActivity.this), new MTagHandler()));
          text.setVisibility(View.VISIBLE);
          123

          MImageGetter、MTagHandler 如下:

          ndroid富文本編輯器支持html的導(dǎo)入與導(dǎo)出源碼

          源碼下載:http://www.dandroid.cn/?p=3278

          android基于exoPlayer 自定義播放器源碼

          源碼下載:http://www.dandroid.cn/?p=3275


          主站蜘蛛池模板: 亚洲一区二区三区四区在线观看| 无码一区二区波多野结衣播放搜索| 好爽毛片一区二区三区四| 国精产品一区一区三区有限公司 | 国产微拍精品一区二区| 精品一区二区三区在线视频观看| 日韩电影在线观看第一区| 国产一区二区三区在线2021 | 无码一区二区三区免费| 正在播放国产一区| 国产成人无码一区二区在线播放 | av无码免费一区二区三区| 国产萌白酱在线一区二区| 老熟妇仑乱视频一区二区| 女人和拘做受全程看视频日本综合a一区二区视频 | 国产在线视频一区| 色屁屁一区二区三区视频国产| 亚洲AV乱码一区二区三区林ゆな| 毛片一区二区三区无码| 亚洲AV色香蕉一区二区| 亚洲国产一区二区三区| 国产精品亚洲一区二区三区在线观看| 国偷自产av一区二区三区| 亚洲AV无码一区二区三区网址| 久久国产精品亚洲一区二区| 高清一区二区三区| 麻豆视频一区二区三区| 国产裸体舞一区二区三区| 日韩人妻无码一区二区三区| 色精品一区二区三区| 亚洲AV网一区二区三区| 国模无码视频一区| 国产一区二区三区高清视频| 亚洲综合色一区二区三区小说| 亚洲一区二区三区写真 | 久久亚洲日韩精品一区二区三区| 日韩伦理一区二区| 无码中文人妻在线一区| 在线成人一区二区| 亚洲av无码一区二区三区在线播放| 丝袜人妻一区二区三区|