TextView顯示文本時是支持一些HTML標簽的(具體支持那些標簽會在下面附錄列出),不會需要先用HTML的static方法fromHtml來轉換一下。
Spanned text = Html.fromHtml(htmlString);
textView.setText(text);
這樣,TextView就會把支持的一些HTML標簽以HTML的形式顯示出來。不過,如果htmlString中含有<img>標簽,並需要在TextView中正確顯示的話就必須做進一步的處理了。
Spanned text = Html.fromHtml(htmlString, imageGetter, null); textView.setText(text);
通過Html的另一個重載的fromHtml方法,指定ImageGetter,來獲取網絡圖片,異步加載的方式來顯示圖片。
下面給出ImageGetter的一個實現類,大部分代碼來自網絡,只針對關鍵部分做了完善,先看代碼,后面詳細說明。

1 public class URLImageGetter implements ImageGetter { 2 Context context; 3 TextView textView; 4 5 public URLImageGetter(Context context, TextView textView) { 6 this.context = context; 7 this.textView = textView; 8 } 9 10 @Override 11 public Drawable getDrawable(String paramString) { 12 final URLDrawable urlDrawable = new URLDrawable(context); 13 14 ImageGetterAsyncTask getterTask = new ImageGetterAsyncTask(urlDrawable); 15 getterTask.execute(paramString); 16 return urlDrawable; 17 } 18 19 public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> { 20 URLDrawable urlDrawable; 21 22 public ImageGetterAsyncTask(URLDrawable drawable) { 23 this.urlDrawable = drawable; 24 } 25 26 @Override 27 protected void onPostExecute(Drawable result) { 28 if (result != null) { 29 urlDrawable.drawable = result; 30 31 URLImageGetter.this.textView.requestLayout(); 32 } 33 } 34 35 @Override 36 protected Drawable doInBackground(String... params) { 37 String source = params[0]; 38 return fetchDrawable(source); 39 } 40 41 public Drawable fetchDrawable(String url) { 42 try { 43 InputStream is = fetch(url); 44 45 Rect bounds = SystemInfoUtils.getDefaultImageBounds(context); 46 Bitmap bitmapOrg = BitmapFactory.decodeStream(is); 47 Bitmap bitmap = Bitmap.createScaledBitmap(bitmapOrg, bounds.right, bounds.bottom, true); 48 49 BitmapDrawable drawable = new BitmapDrawable(bitmap); 50 drawable.setBounds(bounds); 51 52 return drawable; 53 } catch (ClientProtocolException e) { 54 e.printStackTrace(); 55 } catch (IOException e) { 56 e.printStackTrace(); 57 } 58 59 return null; 60 } 61 62 private InputStream fetch(String url) throws ClientProtocolException, IOException { 63 DefaultHttpClient client = new DefaultHttpClient(); 64 HttpGet request = new HttpGet(url); 65 66 HttpResponse response = client.execute(request); 67 return response.getEntity().getContent(); 68 } 69 } 70 71 }
URLDrawable的實現類

1 public class URLDrawable extends BitmapDrawable { 2 protected Drawable drawable; 3 4 public URLDrawable(Context context) { 5 this.setBounds(SystemInfoUtils.getDefaultImageBounds(context)); 6 7 drawable = context.getResources().getDrawable(R.drawable.default_image_min); 8 drawable.setBounds(SystemInfoUtils.getDefaultImageBounds(context)); 9 } 10 11 @Override 12 public void draw(Canvas canvas) { 13 Log.d("test", "this=" + this.getBounds()); 14 if (drawable != null) { 15 Log.d("test", "draw=" + drawable.getBounds()); 16 drawable.draw(canvas); 17 } 18 } 19 20 }
在上述兩個類中,有一點需要注意,那就是ImageGetter返回的Drawble對象的Bounds一定要設定。否則就會出現圖片顯示出來了,但和文字會出現重疊的現象。原因我想是TextView在針對spannable的html字符串中的<img>標簽渲染的時候會根據ImageGetter得到的Drawable對象的Bounds來為圖片預留出空間。所以,在URLDrawable的構造函數中設定了Bounds,其實就是設定圖片寬度為屏幕寬度,高度按照16:9得到。在根據URL獲取網絡圖片以后還需要根據預設的圖片大小來縮放實際的圖片,參見在URLImageGetter類中的fetchDrawable()函數。
當然在URLDrawable在構造中還增加了默認圖片的顯示,這一點對用戶來講很友好,對應用來講也是一個凸顯品牌和情懷的機會:)
getDefaultImageBounds()函數的代碼如下:

1 public static Rect getDefaultImageBounds(Context context) { 2 Display display = ((Activity)context).getWindowManager().getDefaultDisplay(); 3 int width = display.getWidth(); 4 int height = (int) (width * 9 / 16); 5 6 Rect bounds = new Rect(0, 0, width, height); 7 return bounds; 8 }
------------------------------------------------------------------------------------------------------------
附錄:
HTML支持的標簽