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支持的标签