博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

TextView显示HTML文本时<IMG>标签指定图片的显示处理

Posted on 2013-06-27 12:12  haobo  阅读(3180)  评论(2编辑  收藏  举报

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 }
URLImageGetter

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 }
URLDrawable

在上述两个类中,有一点需要注意,那就是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     }
getDefaultImageBounds

------------------------------------------------------------------------------------------------------------

附录:

HTML支持的标签