Android中Textview顯示Html,圖文混排,支持圖片點擊放大

本文首發於網易雲社區html


對於呈現Html文原本說,Android提供的Webview控件能夠獲得很好的效果,但使用Webview控件的弊端是效率相對比較低,對於呈現簡單的html文本的話,殺雞沒必要使用牛刀。另外若是是在Listview中使用的Webview的話,效率則更是低下。android

    然而,Android還提供了android.text.Html類來支持Html的解析,利用這個類,咱們能夠經過Textview來呈現Html文件。不過Html類並非只是全部的標籤。Html的描述以下:web

This class processes HTML strings into displayable styledtext.canvas

Not all HTML tags are supported.緩存


1、解析Html標籤異步

對於純文字的Html文原本說,使用Textview來呈現很方便,一行代碼就能夠輕鬆搞定了,具體以下:ide

contentTextView.setText(Html.formHtml(htmlString));this


2、處理img圖片標籤,實現圖文混排雲計算

通常來講,html文件經常是含有圖片,若是須要在Textview中實現文字和圖片的混排,須要使用ImageGetter。ImageGetter是Html類中一個接口,做用是給img標籤獲取圖片內容,主要提供了一個getDrawable的方法。
url

/** 
* Retrieves images for HTML <img> tags.
*/  
public static interface ImageGetter {  
       /**
        * This methos is called when the HTML parser encounters an
        * <img> tag.  The <code>source</code> argument is the
        * string from the "src" attribute; the return value should be
        * a Drawable representation of the image or <code>null</code>
        * for a generic replacement image.  Make sure you call
        * setBounds() on your Drawable if it doesn't already have
        * its bounds set.
        */  
       public Drawable getDrawable(String source);  
}

解析來須要實現一個ImageGetter,具體以下:

public class MyImageGetter implements ImageGetter {  
     
   WeakReference<TextView> mTextViewReference;  
   Context mContext;  
 
   public MyImageGetter(Context context, TextView textView, int with) {  
       mContext = context.getApplicationContext();  
       mTextViewReference = new WeakReference<TextView>(textView);  
   }  
 
   @Override  
   public Drawable getDrawable(String url) {  
 
       URLDrawable urlDrawable = new URLDrawable(mContext);  
         
       // 異步獲取圖片,並刷新顯示內容  
       new ImageGetterAsyncTask(url, urlDrawable).execute();  
 
       return urlDrawable;  
   }  
     
   public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {  
         
       WeakReference<URLDrawable> mURLDrawableReference;  
       String mUrl;  
 
       public ImageGetterAsyncTask(String url, URLDrawable drawable) {  
           mURLDrawableReference = new WeakReference<URLDrawable>(drawable);  
           mUrl = url;  
       }  
 
       @Override  
       protected Drawable doInBackground(String... params) {  
 
           // 下載圖片,而且使用緩存  
           Bitmap bitmap = DownlaodUtils.getNetworkImageWithCache(mContext, mUrl);      
           BitmapDrawable bitmapDrawable = new BitmapDrawable(mContext.getResources(), bitmap);  
             
           Rect bounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());  
             
           if (mURLDrawableReference.get() != null) {  
               mURLDrawableReference.get().setBounds(bounds);  
           }  
           bitmapDrawable.setBounds(bounds);  
           return bitmapDrawable;  
       }  
 
       @Override  
       protected void onPostExecute(Drawable result) {  
           if (null != result) {  
               if (mURLDrawableReference.get() != null) {  
                   mURLDrawableReference.get().drawable = result;  
               }  
               if (mTextViewReference.get() != null) {  
                   // 加載完一張圖片以後刷新顯示內容  
                   mTextViewReference.get().setText(mTextViewReference.get().getText());  
               }  
           }  
       }  
   }  
     
     
   public class URLDrawable extends BitmapDrawable {  
       protected Drawable drawable;  
 
       public URLDrawable(Context context) {  
           // 設置默認大小和默認圖片  
           Rect bounds = new Rect(0, 0, 100, 100);  
           setBounds(bounds);  
           drawable = context.getResources().getDrawable(R.drawable.default_image);  
           drawable.setBounds(bounds);  
       }  
 
       @Override  
       public void draw(Canvas canvas) {  
           if (drawable != null) {  
               drawable.draw(canvas);  
           }  
       }  
   }  
}  

實現了MyImageGetter以後,則須要實現圖文混排就垂手可得了

  1. MyImageGetter imageGetter = new MyImageGetter(this, contentTextView);  

  2. contentTextView.setText(Html.formHtml(htmlString, imageGetter, null));  


、圖片的點擊放大

前面已經實現了Textview呈現html文本,而且可以圖文混排。但不少狀況下,須要支持點擊圖片後將圖片放大顯示。這樣,咱們須要支持img標籤的點擊處理,可以監聽到點擊事件就能夠實現這個功能了。這裏咱們能夠經過實現TagHandler接口來實現這個功能。首先看下android.text.Html類中的Taghandler接口:

/** 
    * Is notified when HTML tags are encountered that the parser does
    * not know how to interpret.
    */  
   public static interface TagHandler {  
       /**
        * This method will be called whenn the HTML parser encounters
        * a tag that it does not know how to interpret.
        */  
       public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader);  
}  


咱們只需實現TagHandler的handleTag方法來處理img標籤則可,主要是給內容設置一個ClickableSpan,具體以下:

public class MyTagHandler implements TagHandler {  
 
   private mContext;  
     
   public MyTagHandler(Context context) {  
       mContext = context.getApplicationContext();  
   }  
     
   @Override  
   public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {  
 
       // 處理標籤<img>  
       if (tag.toLowerCase(Locale.getDefault()).equals("img")) {  
           // 獲取長度  
           int len = output.length();  
           // 獲取圖片地址  
           ImageSpan[] images = output.getSpans(len-1, len, ImageSpan.class);  
           String imgURL = images[0].getSource();  
             
           // 使圖片可點擊並監聽點擊事件  
           output.setSpan(new ClickableImage(mContext, imgURL), len-1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  
       }  
   }  
     
   private class ClickableImage extends ClickableSpan {  
 
       private String url;  
       private Context context;  
         
       public ClickableImage(Context context, String url) {  
           this.context = context;  
           this.url = url;  
       }  
         
       @Override  
       public void onClick(View widget) {  
           // 進行圖片點擊以後的處理  
       }  
   }  
}  

實現了TagHandler以後,在formHtml傳入實例則可:

MyImageGetter imageGetter = new MyImageGetter(this, contentTextView);  
MyTagHandler tagHandler = new MyTagHandler(this);  
contentTextView.setText(Html.formHtml(htmlString, imageGetter, tagHandler));  
contentTextView.setMovementMethod(LinkMovementMethod.getInstance());  



網易雲產品免費體驗館,無套路試用,零成本體驗雲計算價值。  

本文來自網易雲社區,經做者戚明峯受權發佈


相關文章:
【推薦】 Windows擴展屏開發總結

相關文章
相關標籤/搜索