TextView顯示文本時是支持一些HTML標籤的(具體支持那些標籤會在下面附錄列出),不會須要先用HTML的static方法fromHtml來轉換一下。html
Spanned text = Html.fromHtml(htmlString);
textView.setText(text);
這樣,TextView就會把支持的一些HTML標籤以HTML的形式顯示出來。不過,若是htmlString中含有<img>標籤,並須要在TextView中正確顯示的話就必須作進一步的處理了。canvas
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的實現類ide
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在構造中還增長了默認圖片的顯示,這一點對用戶來說很友好,對應用來說也是一個凸顯品牌和情懷的機會:)fetch
getDefaultImageBounds()函數的代碼以下:this
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 }
------------------------------------------------------------------------------------------------------------url
附錄:spa
HTML支持的標籤