android textView 加载HTML 异步加载网络图片

尊重别人的劳动成果,转发文章请注明出处

概述
大家都知道textview可以格式化html格式的文本内容。是否有了textView就可以实现了一个控件“代替“游览器展示html页面内容呢?
个人觉得不可能那么强大吧。不然怎么会出现了webView这种东西呢?那么现在问题来了,是不是webView就是最完美的选择呢?
个人实践之后得出结论:
1.如果只是格式化html文本类的内容,推荐使用textView,省时省力,还能得到很好的效果
2.如果html页面内容涉及到图片,特别是网络图片加载的,个人觉得尽可能的往webView方向去实现。
两种方式都做过了尝试,下面说一说遇到的问题和解决思路

textView加载html内容问题

1.textView只是加载文本类型html,可以直接使用textView的方法格式化
[java] view plain copy
String message=”html内容”;
TextView textView=new TextView(mContext);
textView.setText(Html.fromHtml(message));
这种方式基本能识别html的标签,对于特殊的,比较新的标签,可以根据实际需求转化成textView能够实现的标签

2.textView加载网络图片
如果加载的html内容中包含图片,那么使用上面的方法则无法实现了,运行之后会出现小方框代替了图片,加载网络图片是一件比较麻烦的事情,需要使用Html.fromHtml的另外一个构造方法。Html.fromHtml(source, imageGetter, tagHandler);
参数说明:source=需要展示的html文本内容,imageGetter=需要继承Html.ImageGetter接口实现逻辑,tagHandler=这个参数表示,当textView解析遇到无法识别的html标签是否发送通知或者消息,如果遇到无法解析的标签,该方法将会被调用。这个没有具体测试过,一般赋值null。

2.1网络图片的加载不能阻塞主线程,因此需要异步加载
2.2加载图片之后无法正常显示(偏小)
2.3重新设置图片大小之后在个别系统上会出现图片错位(这个暂时无法解决,还望有解决办法的共享一下解决思路)

下面是重写的Html.ImageGetter类。
重点思路:先异步加载网络图片,图片加载完成之后重新赋值textView内容,(由于加载的图片会比实际图片偏小,因此我这里将图片的宽拉伸到屏幕宽,将图片的高按照原图等比例拉伸,最致命的一点是:只要重新修改了宽,图片就开始错位。这个看开发者需求,如果小图不影响业务,可以不对图片进行等比例缩放,不缩放就能相对完美实现)

[java] view plain copy
/**
* 重写图片加载接口
*
* @author Ruffian
* @date 2016年1月15日
*
*/
class HtmlImageGetter implements Html.ImageGetter {

/** 
 * 获取图片 
 */  
@Override  
public Drawable getDrawable(String source) {  
    LevelListDrawable d = new LevelListDrawable();  
    Drawable empty = getResources().getDrawable(  
            R.drawable.image_horizontal);  
    d.addLevel(0, 0, empty);  
    d.setBounds(0, 0, PhoneUtils.getScreenWidth(mContext),  
            empty.getIntrinsicHeight());  
    new LoadImage().execute(source, d);  
    return d;  
}  

/** 
 * 异步下载图片类 
 *  
 * @author Ruffian 
 * @date 2016年1月15日 
 *  
 */  
class LoadImage extends AsyncTask<Object, Void, Bitmap> {  

    private LevelListDrawable mDrawable;  

    @Override  
    protected Bitmap doInBackground(Object... params) {  
        String source = (String) params[0];  
        mDrawable = (LevelListDrawable) params[1];  
        try {  
            InputStream is = new URL(source).openStream();  
            return BitmapFactory.decodeStream(is);  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (MalformedURLException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  

    /** 
     * 图片下载完成后执行 
     */  
    @Override  
    protected void onPostExecute(Bitmap bitmap) {  
        if (bitmap != null) {  
            BitmapDrawable d = new BitmapDrawable(bitmap);  
            mDrawable.addLevel(1, 1, d);  
            /** 
             * 适配图片大小 <br/> 
             * 默认大小:bitmap.getWidth(), bitmap.getHeight()<br/> 
             * 适配屏幕:getDrawableAdapter 
             */  
            mDrawable = getDrawableAdapter(mContext, mDrawable,  
                    bitmap.getWidth(), bitmap.getHeight());  

            // mDrawable.setBounds(0, 0, bitmap.getWidth(),  
            // bitmap.getHeight());  

            mDrawable.setLevel(1);  

            /** 
             * 图片下载完成之后重新赋值textView<br/> 
             * mtvActNewsContent:我项目中使用的textView 
             *  
             */  
            mtvActNewsContent.invalidate();  
            CharSequence t = mtvActNewsContent.getText();  
            mtvActNewsContent.setText(t);  

        }  
    }  

    /** 
     * 加载网络图片,适配大小 
     *  
     * @param context 
     * @param drawable 
     * @param oldWidth 
     * @param oldHeight 
     * @return 
     * @author Ruffian 
     * @date 2016年1月15日 
     */  
    public LevelListDrawable getDrawableAdapter(Context context,  
            LevelListDrawable drawable, int oldWidth, int oldHeight) {  
        LevelListDrawable newDrawable = drawable;  
        long newHeight = 0;// 未知数  
        int newWidth = PhoneUtils.getScreenWidth(context);// 默认屏幕宽  
        newHeight = (newWidth * oldHeight) / oldWidth;  
        // LogUtils.w("oldWidth:" + oldWidth + "oldHeight:" +  
        // oldHeight);  
        // LogUtils.w("newHeight:" + newHeight + "newWidth:" +  
        // newWidth);  
        newDrawable.setBounds(0, 0, newWidth, (int) newHeight);  
        return newDrawable;  
    }  
}  

}

调用处代码

[java] view plain copy
String content=”这里是html内容”;
HtmlImageGetter htmlImageGetter = new HtmlImageGetter();
Spanned spanned = Html.fromHtml(content, htmlImageGetter, null);
//mtvActNewsContent:这个textView是我测试项目用到的textView
mtvActNewsContent.setText(spanned);
所以,使用textView加载带网络图片的html内容需求是可以实现的,只是不尽人意。

那么使用webView吧。但是webView加载的是完整的页面内容,需要后台处理好,返回一个页面路径,这个得看个人需求,但是忠告是,图文并茂的页面还是使用webView比较好,但是webView是不是就完美解决了呢?然而并不是,毕竟webView加载页面是页面的内容,效果没有Android原生的好,同事使用webView加载页面在Android系统4.4+开始滑动页面会有明显的卡顿和跳帧,有些简直无法接受

使用腾讯X5SDK优化webView加载

腾讯X5SDK能够加速webView加载,优化滑动卡顿,效果还是比较明显的(亲测),只是使用条件比较苛刻,在国内使用的APP还是可以考虑的。具体使用去官网查看吧,使用遇到什么问题也可以交流一下

http://blog.csdn.net/u014702653/article/details/50585783 转载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值