本文首发于网易云社区

对于呈现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之后,则需要实现图文混排就轻而易举了

  1. MyImageGetter imageGetter = new MyImageGetter(this, contentTextView);

  2. 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());  

网易云产品免费体验馆,无套路试用,零成本体验云计算价值。

本文来自网易云社区,经作者戚明峰授权发布

相关文章:
【推荐】 Windows扩展屏开发总结

Android中Textview显示Html,图文混排,支持图片点击放大的更多相关文章

  1. TextView + Spanned实现图文混排以及图片点击交互

    最近要实现图文混排的需求,webview过大,所以想到了用SpannableStringBuilder来实现. 不过参考了大量国内文章,大多数是教你如何实现图文混排,并没有提及图片点击交互的.有翻阅了 ...

  2. DIV+CSS 图文混排的图片居中办法

    不少人为了让 Div 图文混排的图片可以居中,给 IMG 套各式各样的 SPAN.DIV.LI 等等,以便于使用 text-align来进行居中. <div>图文混排 <br> ...

  3. Unity插件之NGUI学习(5)—— 创建Label图文混排及文字点击

    创建一个新的Scene,并按 Unity插件之NGUI学习(2)创建UI Root. 准备工作,制作Font.如今Project窗体创建一个Font目录.然后从系统自带字体目录中选择自己须要的字体,我 ...

  4. iOS 图文混排 链接 可点击

    对于这个话题 我想到 1 第一个解决方法就是使用 webView 比较经典 把所有复杂工作都交给控件本身去处理了,  但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实 ...

  5. 关于Android中TextView显示多个空格

    一.直接填写文字,输入多少,显示多少,如下: android:text="AAA     AAA"     ————————>显示:AAA     AAA 二.通过设置str ...

  6. [UGUI]图文混排(六):点击区域

    点击区域可以分成两部分来分析: 0.Rect 搜索api:Rect和Rect.Rect,可以知道: 在GUI和GUILayout中,Rect的原点在左上角,向右为x轴正方向,向下为y轴正方向: 除此之 ...

  7. HTML5[8]: 图文混排,图片与文字居中对齐

    <img src="image.png"><span>999</span> img { /* ...  */ vertical-align: t ...

  8. 简单的Coretext 图文混排

    在很多新闻类或有文字展示的应用中现在都会出现图文混排的界面例如网易新闻等,乍一看去相似一个网页,其实这样效果并非由UIWebView 加载网页实现.现在分享一种比较简单的实现方式 iOS sdk中为我 ...

  9. CoreText实现图文混排之文字环绕及点击算法

    系列文章: CoreText实现图文混排:http://www.jianshu.com/p/6db3289fb05d CoreText实现图文混排之点击事件:http://www.jianshu.co ...

随机推荐

  1. 4_bootstrap之栅格系统

    4.栅格系统 4.1.简述栅格系统 为了方便在布局容器中进行网页的布局操作. BootStrap提供了一套专门用于响应式开发布局的栅格系统. 栅格系统将一行分为12列,通过设定元素占用的列数来 布局元 ...

  2. 【转】深入了解CPU两大架构ARM与X86

    来自:https://blog.csdn.net/u014641018/article/details/53484565 重温下CPU是什么 中央处理单元(CPU)主要由运算器.控制器.寄存器三部分组 ...

  3. jquery ui的css设计二

    上一篇见这里 本篇重点说一下其换肤功能 换肤一般是指改变控件的字体颜色,背景颜色,边框颜色,hover上去的颜色,背景图片,很少再会涉及修改其长宽,字体类型什么的. 以这个版本的CSS为观察对象,可以 ...

  4. EL的基本使用

    总结:EL操作的是作用域 <body> <% Users users = new Users("lisi","lisi123","l ...

  5. 03-SSH综合案例:商城表关系分析

    1.2   设计页面: 静态页面: 1.3    数据库分析与设计: 一般是一个Java类就对应一个表,有哪些类?那看你有哪些实体啊?一般一个模块对应一个实体 有用户模块就会有用户的一个实体,就会有用 ...

  6. java文档打包成压缩包并且下载

    需求,根据产品ID查询产品详情,产品详情会返回产品的一些文案,以及图片的url.需要做成,将文案信息记录在一个txt文档中,然后图片下载到文件夹,最后下载到本地,下载后自动删除刚才生成的文件夹以及文件 ...

  7. 切线空间(Tangent Space)

    http://download.autodesk.com/global/docs/maya2012/zh-cn/index.html?url=files/Polygons_nodes_Tangent_ ...

  8. Ice_cream’s world II(最小树形图,加虚点)

    Ice_cream’s world II http://acm.hdu.edu.cn/showproblem.php?pid=2121 Time Limit: 3000/1000 MS (Java/O ...

  9. 企业招聘:UX设计师需要满足他们哪些期望?

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具.   为了确定2017年最有价值的用户体验技能和特质,我特地参考了150多份工作要求.最后,得出了以下 ...

  10. popupWindow自适应大小

    // popupWindow自适应大小 popupWindow = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP ...