Android中Textview显示带html文本三-------【Textview显示网络图片】

转自:

http://www.cnblogs.com/mxgsa/archive/2012/12/20/2823666.html

上篇遗留下来一个问题就是:显示网络图片,我用android2.3的系统,可以显示图片出来,并且如果图片比较大,应用会卡的现象,肯定是因为使用主线程去获取网络图片造成的,但如果我用android4.0以上的系统运行,则不能显示图片,只显示小方框。

究其原因,是在4.0的系统上执行的时候报错了,异常是:android.os.NetworkOnMainThreadException 经过查文档,原来是4.0系统不允许主线程(UI线程)访问网络,因此导致了其异常。说白了就是在主线程上访问网络,会造成主线程挂起,系统不允许使用了。

看到Android4.0不允许主线程(UI线程)访问网络,立马脑子就想起来 ,不能用主线程访问,可以开另外一个线程,把图片下到本地sd卡中,之后在赋值到TextView里面。不急着来代码,我和大家在把这个逻辑在理一下:获取图片路径——异步下载图片——完成下载后重新赋值Textview

想到这里,我就准备自己亲自实践下......于是,我就简单的写了文件下载类DownLoadUtils,有四个事件就是开始下载,下载中(返回进度),完成下载后,下载出错!具体代码就不贴出来了。大家可以自己去写一个,下载文件的代码搜下都有!下载类里面用到了线程和Handler的的使用,下篇我具体讲下这个。

下面是Activity页面处理代码:

复制代码
private TextView tView;
    private DownLoadUtils downLoadUtils;
    //保存文件路径
    private final String path="/mnt/sdcard/downimg";
    //设置text的值
    String sText = "测试图片信息:<br><img src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" />";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mxgsa_activity);
        findControl();
        setData();
    }

    private void findControl() {
        tView = (TextView) findViewById(R.id.tvImage);
    }
    

    private void setData() {
        //初始化下载类
        downLoadUtils=new DownLoadUtils();
        //设置下载类监听事件
        downLoadUtils.setOnDownloadListener(onDownloadListener);
        //给Textview赋值
        tView.setText(Html.fromHtml(sText, imageGetter, null));
    }

    final Html.ImageGetter imageGetter = new Html.ImageGetter() {
        public Drawable getDrawable(String source) {
            Drawable drawable = null;
            String fileString=path+String.valueOf(source.hashCode());
            Log.i("DEBUG", fileString+"");
            Log.i("DEBUG", source+"");
            //判断SD卡里面是否存在图片文件
            if (new File(fileString).exists()) {
                Log.i("DEBUG", fileString+"  eixts");
                //获取本地文件返回Drawable
                drawable=Drawable.createFromPath(fileString);
                //设置图片边界
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            }else {
                Log.i("DEBUG", fileString+" Do not eixts");
                //启动新线程下载
                downLoadUtils.download(source, path+String.valueOf(source.hashCode()));
                return drawable;
            }
            
        };

    };
    OnDownloadListener onDownloadListener=new OnDownloadListener() {
        
        //下载进度
        public void onDownloadUpdate(DownLoadUtils manager, int percent) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", percent+"");
        }
        
        //下载失败
        public void onDownloadError(DownLoadUtils manager, Exception e) {
            // TODO Auto-generated method stub
            
        }
        
        //开始下载
        public void onDownloadConnect(DownLoadUtils manager) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", "Start  //");
        }
        
        //完成下载
        public void onDownloadComplete(DownLoadUtils manager, Object result) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", result.toString());
            //替换sTExt的值,就是把图片的网络路径换成本地SD卡图片路径(最早想法,可以不需要这样做了)
            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));
            //再一次赋值给Textview
            tView.setText(Html.fromHtml(sText, imageGetter, null));
        }
    };
复制代码

下面来简单的介绍下上面的代码,最重要的就是有两点,就是第一次把sText赋值Textview,在Html.ImageGetter的重载方法里面去判断该图片文件是否已经下载,如果已经下载,就直接读取SD卡里面的图片文件,如上篇所讲的Textview显示本地图片

//获取本地文件返回Drawable
                drawable=Drawable.createFromPath(fileString);
                //设置图片边界
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

如果没有下载就开启一个下载线程

//启动新线程下载
downLoadUtils.download(source, path+String.valueOf(source.hashCode()));

第二个重点就是监听下载完成事件,完成下载以后,重新给Textview赋值

复制代码
OnDownloadListener onDownloadListener=new OnDownloadListener() {
        
        //下载进度
        public void onDownloadUpdate(DownLoadUtils manager, int percent) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", percent+"");
        }
        
        //下载失败
        public void onDownloadError(DownLoadUtils manager, Exception e) {
            // TODO Auto-generated method stub
            
        }
        
        //开始下载
        public void onDownloadConnect(DownLoadUtils manager) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", "Start  //");
        }
        
        //完成下载
        public void onDownloadComplete(DownLoadUtils manager, Object result) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", result.toString());
            //替换sTExt的值,就是把图片的网络路径换成本地SD卡图片路径(最早想法,可以不需要这样做了)
            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));
            //再一次赋值给Textview
            tView.setText(Html.fromHtml(sText, imageGetter, null));
        }
    };
复制代码

这样做了之后,网络图片就可以显示在Textview里面。在网络正常的情况下,如果是相同图片只需要下载一次,这样可以节省了手机的流量。

我还有一种解决方案就是不需要给Textview赋两次值,就是首先解析出来图片路径,然后下载图片,最后赋值给Textview,其实道理是一样的,之前的做法是通过重载方法解析出来图片的路径然后下载图片。只不过是多了一个赋值,没有任何影响。大家有好的思路,也可以介绍下。

以上观点只代表我个人意见。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android ,可以通过以下两种方式在 TextView 显示图片: 1. 使用 HTML 标记 可以在 TextView 使用 HTML 标记来显示图片。具体做法如下: 在 strings.xml 定义一个包含 HTML 标记的字符串: ```xml <string name="html_text">这是一个包含图片文本:<br><img src="android.resource://com.example.app/drawable/ic_launcher"/></string> ``` 在代码获取该字符串,并将其设置给 TextView: ```java textView.setText(Html.fromHtml(getString(R.string.html_text))); ``` 其,`android.resource://com.example.app/drawable/ic_launcher` 是图片的路径,需要根据实际情况进行修改。 2. 使用 SpannableString 使用 SpannableString 可以在 TextView 插入图片,并且可以控制图片的大小和位置。具体做法如下: ```java SpannableString spannableString = new SpannableString("这是一个包含图片文本:"); Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE); spannableString.setSpan(imageSpan, spannableString.length() - 1, spannableString.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableString); ``` 其,`R.drawable.ic_launcher` 是图片的资源 ID,需要根据实际情况进行修改。`setBounds()` 方法用于设置图片的大小和位置,`ALIGN_BASELINE` 表示将图片和基线对齐。`setSpan()` 方法用于将图片插入到 SpannableString

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值