Android中Textview顯示Html,圖文混排,支援圖片點選放大
本文首發於 ofollow,noindex"> 網易雲社群
對於呈現Html文字來說,Android提供的Webview控制元件可以得到很好的效果,但使用Webview控制元件的弊端是效率相對比較低,對於呈現簡單的html文字的話,殺雞不必使用牛刀。另外如果是在Listview中使用的Webview的話,效率則更是低下。
然而,Android還提供了android.text.Html類來支援Html的解析,利用這個類,我們可以通過Textview來呈現Html檔案。不過Html類並不是只是所有的標籤。Html的描述如下:
This class processes HTML strings into displayable styledtext.
Not all HTML tags are supported.
一、解析Html標籤
對於純文字的Html文字來說,使用Textview來呈現很方便,一行程式碼就可以輕鬆搞定了,具體如下:
contentTextView.setText(Html.formHtml(htmlString));
二、處理img圖片標籤,實現圖文混排
一般來說,html檔案常常是含有圖片,如果需要在Textview中實現文字和圖片的混排,需要使用ImageGetter。ImageGetter是Html類中一個介面,作用是給img標籤獲取圖片內容,主要提供了一個getDrawable的方法。
/** * 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之後,則需要實現圖文混排就輕而易舉了
-
MyImageGetter imageGetter = new MyImageGetter(this, contentTextView);
-
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());
網易雲產品 免費體驗館 ,無套路試用,零成本體驗雲端計算價值。
本文來自網易雲社群,經作者戚明峰授權釋出