1. 程式人生 > >Android TextView載入html圖片詳解

Android TextView載入html圖片詳解

       學Android的時候突然想到一個問題:怎麼用TextView控制元件顯示帶有格式的文字,可否使用Html佈局?查了下Android 幫助文件,其提供了android.text.Html類和Html.ImageGetter、Html.TagHandler介面

        其實本不打算寫這篇博文的,但看到網路上關於此的文章,基本是:你抄我,我抄你,大家抄來抄去,有用的也就那麼一兩篇文章,而且說得不明不白,網路就是如此,盜版也成為了一種文化,這就是所謂的拿來主義吧。當然不否認大牛的辛勤勞作,寫出的高質量文章;其次是學以致用,個人習慣--總結一下。

先看截圖:

               


        我們平常使用TextView的setText()方法傳遞String引數的時候其實是呼叫的public final void setText (CharSequence text)方法:

  1. /** 
  2.     * Sets the string value of the TextView. TextView <em>does not</em> accept 
  3.     * HTML-like formatting, which you can do with text strings in XML resource files. 
  4.     * To style your strings, attach android.text.style.* objects to a
     
  5.     * {@link android.text.SpannableString SpannableString}, or see the 
  6.     * <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources"> 
  7.     * Available Resource Types</a> documentation for an example of setting  
  8.     * formatted text in the XML resource file. 
  9.     *
     
  10.     * @attr ref android.R.styleable#TextView_text 
  11.     */
  12.    @android.view.RemotableViewMethod  
  13.    publicfinalvoid setText(CharSequence text) {  
  14.        setText(text, mBufferType);  
  15.    }  
        而String類是CharSequence的子類,在CharSequence子類中有一個介面Spanned,即類似html的帶標記的文字,我們可以用它來在TextView中顯示html。在上面Android原始碼註釋中有提及TextView does not accept HTML-like formatting。

       android.text.Html類共提供了三個方法,可以到Android幫助文件檢視。

  1. publicstatic Spanned fromHtml (String source)  
  2. publicstatic Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)  
  3. publicstatic String toHtml (Spanned text)  

       通過使用第一個方法,可以將Html顯示在TextView中:

  1. publicvoid onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.         setContentView(R.layout.main);  
  4.         TextView tv=(TextView)findViewById(R.id.textView1);  
  5.         String html="<html><head><title>TextView使用HTML</title></head><body><p><strong>強調</strong></p><p><em>斜體</em></p>"
  6.                 +"<p><a href=\"http://www.dreamdu.com/xhtml/\">超連結HTML入門</a>學習HTML!</p><p><font color=\"#aabb00\">顏色1"
  7.                 +"</p><p><font color=\"#00bbaa\">顏色2</p><h1>標題1</h1><h3>標題2</h3><h6>標題3</h6><p>大於>小於<</p><p>" +  
  8.                 "下面是網路圖片</p><img src=\"http://avatar.csdn.net/0/3/8/2_zhang957411207.jpg\"/></body></html>";  
  9.         tv.setMovementMethod(ScrollingMovementMethod.getInstance());//滾動
  10.         tv.setText(Html.fromHtml(html));      
  11.     }  
效果:

              
        可以看出,字型效果是顯示出來了,但是圖片卻沒有顯示。要實現圖片的顯示需要使用Html.fromHtml的另外一個重構方法:public static Spanned fromHtml (String source, Html.ImageGetterimageGetter, Html.TagHandler tagHandler)其中Html.ImageGetter是一個介面,我們要實現此介面,在它的getDrawable(String source)方法中返回圖片的Drawable物件才可以。
修改後的程式碼:

  1. ImageGetter imgGetter = new Html.ImageGetter() {  
  2.         public Drawable getDrawable(String source) {  
  3.               Drawable drawable = null;  
  4.               URL url;    
  5.               try {     
  6.                   url = new URL(source);    
  7.                   drawable = Drawable.createFromStream(url.openStream(), "");  //獲取網路圖片
  8.               } catch (Exception e) {    
  9.                   returnnull;    
  10.               }    
  11.               drawable.setBounds(00, drawable.getIntrinsicWidth(), drawable  
  12.                             .getIntrinsicHeight());  
  13.               return drawable;   
  14.         }  
  15. };  

這裡主要是實現了Html.ImageGetter介面,通過圖片的URL地址獲取相應的Drawable例項。
不要忘了在Mainifest檔案中加入網路訪問的許可權:
  1. <uses-permission android:name="android.permission.INTERNET" />  

 友情提示:通過網路獲取圖片是一個耗時的操作,最好不要放在主執行緒中,否則容易引起阻塞。
上面介紹的是顯示網路上的圖片,但如何顯示本地的圖片呢:


  1.    ImageGetter imgGetter = new Html.ImageGetter() {  
  2.         public Drawable getDrawable(String source) {  
  3.               Drawable drawable = null;  
  4.               drawable = Drawable.createFromPath(source); //顯示本地圖片
  5.               drawable.setBounds(00, drawable.getIntrinsicWidth(), drawable  
  6.                             .getIntrinsicHeight());  
  7.               return drawable;   
  8.         }  
  9. };  
只需將source改為本地圖片的路徑便可,在這裡我使用的是:
  1. String source;  
  2. source=getFilesDir()+"/ic_launcher.png";  

THE END

一、[Android例項]實現TextView裡的文字有不同顏色

轉eoe:http://www.eoeandroid.com/thread-4496-1-1.html

import android.text.Html;

TextView t3 = (TextView) findViewById(R.id.text3);
        t3.setText(
            Html.fromHtml(
                "<b>text3:</b>  Text with a " +
                "<a href=\"http://www.google.com\">link</a> " +
                "created in the Java source code using HTML."));

二、TextView顯示html檔案中的圖片

轉javaeye:http://da-en.javaeye.com/blog/712415

我們知道要讓TextView解析和顯示Html程式碼。可以使用
Spanned text = Html.fromHtml(source);
tv.setText(text);
來實現,這個用起來簡單方便。
但是,怎樣讓TextView也顯示Html中<image>節點的影象呢?

我們可以看到fromHtml還有另一個重構:
fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)

實現一下ImageGetter就可以讓圖片顯示了:
ImageGetter imgGetter = new Html.ImageGetter() {
             @Override
             public Drawable getDrawable(String source) {
                   Drawable drawable = null;
                   drawable = Drawable.createFromPath(source);  // Or fetch it from the URL
                   // Important
                   drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
                                 .getIntrinsicHeight());
                   return drawable;
             }
};

至於TagHandler,我們這裡不需要使用,可以直接傳null。
參考文件:
http://tech-droid.blogspot.com/2010/06/textview-with-html-content.html英語好的朋友就直接看英文文件吧。

三、Android---文字中插入表情

       這段時間在做一個簡訊專案,需要實現簡訊中插入表情的功能,本一位非常困難,經過一段時間的研究,發現還是比較簡単的,現在總結如下。

       以簡訊輸入框為例,簡訊的輸入框是一個EditText,它的append方法不僅可以加入字串,還可以新增HTML標記。以下就是使用HTML標記新增表情的具體操作。

   首先需要構建一個ImageGetter,作用是通過HTML標記獲得對應在res目錄下的圖片:

       ImageGetter imageGetter = new ImageGetter() {  
        @Override
       public Drawable getDrawable(String source) {
       int id = Integer.parseInt(source);

      //根據id從資原始檔中獲取圖片物件
       Drawable d = getResources().getDrawable(id);
       d.setBounds(0, 0, d.getIntrinsicWidth(),d.getIntrinsicHeight());
        return d;
       }
       };          

然後就可以直接往EditText檢視中新增

       inputLable.append(Html.fromHtml("<img src='"+clickedImageId+"'/>", imageGetter, null));                  

  其中 Html.fromHtml("<img src='"+clickedImageId+"'/>"就是HTML的圖片標記,在Android中支援了部分HTML標記的使用(這方面我還在繼續研究),HTML標記必須被Html.fromHtml修飾。imageGetter即為之前建立的ImageGetter型別的物件。

很簡單的幾句程式碼就解決了問題,不僅在EditText中,在TextView中同樣可以這樣插入圖片。

效果圖:

四、android 簡訊字元轉表情顯示過程 android 的簡訊實現方式普通使用者適應的話需要長時間的使用才能習慣,將andorid的簡訊模式設定成我們常用的(一般人使用者)的習慣。在檢視字元轉圖片的過程中可以猜測出騰訊的QQ表情的原理應該是一樣的只是在傳送非常用的表情時是將byte資料轉換為image.

以下程式碼摘錄至android原始碼裡面的MMS專案,其中的

package com.android.mms.ui 裡的 MessageListItem.java

package com.android.mms.util 裡的 SmileyParser.java

/***
     * 
         * 
此方法描述的是:注意此方法在做表情轉換的準備了

         * @author:[email protected],[email protected]
         * @version: 2010-5-13 
下午03:31:13
     */
    private void bindCommonMessage(final MessageItem msgItem) {
        if (mDownloadButton != null) {
            mDownloadButton.setVisibility(View.GONE);
            mDownloadingLabel.setVisibility(View.GONE);
        }
        // Since the message text should be concatenated with the sender's
        // address(or name), I have to display it here instead of
        // displaying it by the Presenter.
        mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());

        // Get and/or lazily set the formatted message from/on the
        // MessageItem. Because the MessageItem instances come from a
        // cache (currently of size ~50), the hit rate on avoiding the
        // expensive formatMessage() call is very high.
        CharSequence formattedMessage = msgItem.getCachedFormattedMessage();
        if (formattedMessage == null) { //
肯定為null應為msgItem.formattedMessage從誕生來就沒被注意過一次

            formattedMessage = formatMessage(msgItem.mContact, msgItem.mBody,   //
重點到了
                                             msgItem.mSubject, msgItem.mTimestamp,
                                             msgItem.mHighlight);
            msgItem.setCachedFormattedMessage(formattedMessage);
        }
        mBodyTextView.setText(formattedMessage);

        if (msgItem.isSms()) {
            hideMmsViewIfNeeded();
        } else {
            Presenter presenter = PresenterFactory.getPresenter(
                    "MmsThumbnailPresenter", mContext,
                    this, msgItem.mSlideshow);
            presenter.present();

            if (msgItem.mAttachmentType != WorkingMessage.TEXT) {
                inflateMmsView();
                mMmsView.setVisibility(View.VISIBLE);
                setOnClickListener(msgItem);
                drawPlaybackButton(msgItem);
            } else {
                hideMmsViewIfNeeded();
            }
        }

        drawLeftStatusIndicator(msgItem.mBoxId);
        drawRightStatusIndicator(msgItem);
    }
//------------------------------------------------------------------------------

/***
     * 
         * 
此方法描述的是:開始轉換了哦

         * @author:[email protected],[email protected]
         * @version: 2010-5-13 
下午03:32:52
     */
    private CharSequence formatMessage(String contact, String body, String subject,
                                       String timestamp, String highlight) {
        CharSequence template = mContext.getResources().getText(R.string.name_colon); //
遇到鬼了     &lt;主題:
<xliff:g id="SUBJECT">%s</xliff:g>&gt;"
        SpannableStringBuilder buf =                   //
把他當作StringBuffer只是它可以放的不是 String 而已他能放跟多型別的東西

            new SpannableStringBuilder(TextUtils.replace(template,
                new String[] { "%s" },
                new CharSequence[] { contact })); //
替換成聯絡人

        boolean hasSubject = !TextUtils.isEmpty(subject); //主題
        if (hasSubject) {
            buf.append(mContext.getResources().getString(R.string.inline_subject, subject)); //buff
先在是 聯絡人 主題 XXXX      eg wuyi <主題:dsadasdsa> 我愛我家
        }

        if (!TextUtils.isEmpty(body)) {
            if (hasSubject) {
                buf.append(" - "); //
如果內容有主題有就+ " - "    eg wuyi <主題
:sdsadsadsa> - 
            }
            SmileyParser parser = SmileyParser.getInstance(); //
獲得表情類了哦

            buf.append(parser.addSmileySpans(body)); //
追查 急切關注中
        }
        if (!TextUtils.isEmpty(timestamp)) {
            buf.append("\n");
            int startOffset = buf.length();

            // put a one pixel high spacer line between the message and the time stamp as requested
            // by the spec.
            //
把之間的資訊和時間戳的要求間隔一個畫素的高線

            //
由規範
            buf.append("\n");
            buf.setSpan(new AbsoluteSizeSpan(3), startOffset, buf.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            startOffset = buf.length();
            buf.append(timestamp);
            buf.setSpan(new AbsoluteSizeSpan(12), startOffset, buf.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            // Make the timestamp text not as dark 
改變某區域顏色時間的地方為特殊顏色

            int color = mContext.getResources().getColor(R.color.timestamp_color);
            buf.setSpan(new ForegroundColorSpan(color), startOffset, buf.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        if (highlight != null) {
            int highlightLen = highlight.length();

            String s = buf.toString().toLowerCase();
            int prev = 0;
            while (true) {
                int index = s.indexOf(highlight, prev);
                if (index == -1) {
                    break;
                }
                buf.setSpan(new StyleSpan(Typeface.BOLD), index, index + highlightLen, 0);
                prev = index + highlightLen;
            }
        }
        return buf;
    }

//------------------------------------------------------------

/**
     * Adds ImageSpans to a CharSequence that replace textual emoticons such
     * as :-) with a graphical version.
     * 
     * @param text A CharSequence possibly containing emoticons
     * @return A CharSequence annotated with ImageSpans covering any
     *         recognized emoticons.
     * 
新增ImageSpans一個CharSequence的表情符號代替文字等     *如用圖形版本:-)

     * 
核心是把表情字元替換成ImageSpans的物件
     */
    public CharSequence addSmileySpans(CharSequence text) {
        SpannableStringBuilder builder = new SpannableStringBuilder(text);

        Matcher matcher = mPattern.matcher(text);
        while (matcher.find()) {
            int resId = mSmileyToRes.get(matcher.group());
            //
注意下面的一塊有點不好理解哦但是是核心

            builder.setSpan(new ImageSpan(mContext, resId), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        return builder;
    }

總結:

     android 在將字元轉化為表情影象其核心程式碼為

builder.setSpan(new ImageSpan(mContext, resId), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
原理過程是先匹配到表情字元然後通過new ImageSpan(上下文,表情地址)繪製出一個ImageView然後替換掉表情字元。

五、 

Android TextView 支援的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://www.cnblogs.com/playing/archive/2011/03/17/1987033.html

相關推薦

Android TextView載入html圖片

       學Android的時候突然想到一個問題:怎麼用TextView控制元件顯示帶有格式的文字,可否使用Html佈局?查了下Android 幫助文件,其提供了android.text.Html類和Html.ImageGetter、Html.TagHandler介

Android webView載入html程式碼

最近的專案需要做一個如同微信中的騰訊新聞的功能,如下圖所示: 直接上關鍵程式碼: 佈局: Xml程式碼  <?xmlversion="1.0"encoding="utf-8"?> <RelativeLayoutxmlns:android="htt

android TextView 載入html 顯示圖片並且新增img標籤點選事件工具類 富文字 圖文混排 圖片大小調整

注意,本人部落格主要是為了自己記錄,如果有問題歡迎反饋哈。 android的TextView可以載入html程式碼,並且識別他們的標籤,用的方法就是setText(Html.fromHtml(source)),其中source是指定的字串,包含html標籤,用setText

android textView 載入HTML 非同步載入網路圖片

/** * 重寫圖片載入介面 * * @author Ruffian * @date 2016年1月15日 * */ class HtmlImageGetter implements Html.ImageGetter { /** * 獲取圖片 */ @Ov

android webview載入html圖片自適應手機螢幕大小&點選檢視大圖

我們在開發中,顯示資訊詳情時,一般後臺會給出html文字,在Android端一般採用webview控制元件來展示,但是後臺給出的html文字一般是給電腦端用的,沒有自適配手機,導致手機端圖片顯示過大,需要左右移動來檢視全圖。下面給出幾種實用方法,達到在手機端用webvi

Android Glide Google 推薦載入圖片框架(載入圖片篇)

每個時間,都會有不同的心情,學會享受現在的心情,無論快樂亦或悲傷的心情,都是生活的點滴印記。 看到這個,你一定會說,我現在在用ImageLoader,Picasso,Fresco或其它框架中的圖片載入,都挺好用的,為什麼要選用Glide呢? 答

Android開發技巧——TextView載入HTML圖片及程式碼顯示問題

前幾天在做一個Gradle使用者指南的應用程式,使用的是TextView來載入HTML內容(至於為什麼不用WebView,我也沒有認真使用並比較過,也許以後會換吧),其中遇見了一些糾結的問題,所幸主要的問題都一一解決了。 下面說一下遇見的幾個問題及我的解決方法。 TextV

Android TextView載入帶有多張圖片HTML,並且解決圖片造成的OOM

相信大家都有過需求需要載入從後臺返回的部分HTML程式碼到我們的Android手機上需求,現有的android 原生控制元件有WebView 和 TextView 可以去載入HTML,由於現在的需求我們需要記載一段HTML程式碼在RecyclerView

佔位圖和圖片載入專案實戰

佔位圖(兜底圖): 真實圖片太大還沒有載入完之前先用一張佔位圖表示這個位置將來會有圖片或者說明這個位置是有圖片的但是不知道什麼原因真正的圖片沒有加載出來使用者只能看到這張佔位圖; 什麼是圖片懶載入: 懶載入也就是延遲載入,當訪問一個頁面的時候,先把img元素渲染出來,但是不給它真

Android TextView使用HTML處理字型樣式、顯示圖片

         學Android的時候突然想到一個問題:怎麼用TextView控制元件顯示帶有格式的文字,可否使用Html佈局?查了下Android 幫助文件,其提供了android.text.Html類和Html.ImageGetter、Html.TagHandler介

android WebView載入html 處理的圖片過寬的工具類 (過寬的控制到100%,正常尺寸的不放大)

參考 部落格: 小曾同志的專欄: https://blog.csdn.net/u010023795/article/details/53509495 工具類 import org.jsoup.Jsoup; import org.jsoup.nodes.Document; impor

android textview設定html圖片顯示問題

顯示本地mipmap/drawable檔案下圖片: string info = "<img src=\"img_talk_peaple_only\"/>"; text.setText(Html.fromHtml(info, new Html.Im

Android WebView載入Html文字不能適配,以及圖片中間有空白的問題

1.WebView載入Html文字的正確方式 webView.loadData(html, "text/html; charset=utf-8", "utf-8"); 2.但是如果文字中帶圖片的

Android學習之TextView顯示html圖片的方法

今天在使用TextView顯示html圖片的時候,發現圖片展示不出來,因為有很多html標記是不支援的,只支援一部分,效果如下: 文字效果有,但是圖片出不來 要實現圖片的顯示需要使用Html.fromHtml的另外一個重構方法: public stat

TextView載入 html 程式碼,藉助Glide載入jpg or gif 等圖片格式

app載入網頁資料,可能大部分人都習慣用WebView去實現,簡單方便,但是有些時候從api返回的html資料中,是不帶html 的css樣式的,這時候html 加載出來的文字會顯示不整潔,達不到自己想要的效果,甚至文字很小,如果用WebView去顯示的話,使用

Android Studio使用教程圖文

識別 由於 group 之前 而是 ces doc java代碼 風格 Android Studio是一款非常專業的Android集成開發環境工具,那麽,Android Studio怎麽用呢?針對不知道Android Studio怎麽使用的朋友們,本文就為大家圖文詳細介紹A

Android中的windowSoftInputMode屬性

stun -h oid 中文意思 ecif andro 標題 進行 模式 如何實現軟鍵盤不自動彈出,使用的方法是設置android:windowSoftInputMode屬性。那麽,這個屬性到底是幹什麽的,他有什麽作用呢?今天這篇文章,就是探索android:win

Android之build.prop屬性

lin logs generated reg dconf hostname product att make 註:本篇文章是基於MSD648項目(AndroidTV)的prop進行說明。 Android版本:4.4.4 內核版本:3.10.86 1.生成build.

aNDROID特效五種TOasT

smo android roi aid window mobile ongl ast andro aNDROID%E5%92%8CWINDOWsMOBILE http://music.baidu.com/songlist/495782919 http://music.b

關於瀏覽器解析html全過程

col 頁面 def 動態 lib href web 圖片 使用 本人web前端菜鳥一枚,第一次在這裏發博客梳理知識,知識都是從各地方查閱引用以及自己的理解得來,有什麽錯誤的地方歡迎指正。 DOM文檔通常加載的步驟: 1.解析HTML結構。 2.加載外部腳本和樣式表文