Maison >interface Web >tutoriel HTML >Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose

Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose

WBOY
WBOYoriginal
2016-06-21 09:10:031590parcourir

Textview可以显示基本的HTML标签

<a href="..."><b><big><blockquote><br><cite><dfn><div align="..."><em><font size="..." color="..." face="..."><h1><h2><h3><h4><h5><h6><i><img  src="..." alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" ><p><small><strike><strong><sub><sup><tt><u>

下面着重说一下Textview显示“img”标签,也许看到这里,大家都会想到就是构建ImageGetter,重载一下其 public Drawable getDrawable(String source)方法,获取该路径的图片。

例如:

final Html.ImageGetter imageGetter = new Html.ImageGetter() {            public Drawable getDrawable(String source) {                    return drawable;    };};

下面来说下public Drawable getDrawable(String source)这个方法,source就是图片路径!

例如:

final String sText = "测试图片信息:<br><img  src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" ><img  src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" >";tView.setText(Html.fromHtml(sText, imageGetter, null));

则source就是img的src的值,既是:http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg这个图片路径

当然这个Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose 这个路径既可以是网络图片,也可以本地图片,项目资源图片

例如:本地图片Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose   项目资源图片 Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose

但是不同的路径,ImageGetter的重载处理方法都不一样,下面来一一介绍各种的处理方式.

第一种:本地图片

final String sText2 = "测试图片信息:<img  src=\"/mnt/sdcard/temp/1.jpg\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" >";tView.setText(Html.fromHtml(sText2, imageGetter, null));final Html.ImageGetter imageGetter = new Html.ImageGetter() {    public Drawable getDrawable(String source) {        Drawable drawable=null;    drawable=Drawable.createFromPath(source);        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());    return drawable;  };}

第二种:项目资源图片

final String sText1 = "测试图片信息:<img  src=\""+R.drawable.market_none_image+"\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" >";tView.setText(Html.fromHtml(sText1, imageGetter, null));final Html.ImageGetter imageGetter = new Html.ImageGetter() {    public Drawable getDrawable(String source) {        Drawable drawable=null;    int rId=Integer.parseInt(source);    drawable=getResources().getDrawable(rId);    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());    return drawable;    };}

第三种:网络图片

final String sText = "测试图片信息:<br><img  src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" >";tView.setText(Html.fromHtml(sText, imageGetter, null));final Html.ImageGetter imageGetter = new Html.ImageGetter() {    public Drawable getDrawable(String source) {        Drawable drawable=null;    URL url;    try {        url = new URL(source);        drawable = Drawable.createFromStream(url.openStream(), "");    } catch (Exception e) {        e.printStackTrace();        return null;    }    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());                return drawable;     };}


通过这三个方式,可以看出,不同的图片路径,得到图片的处理方式不同,大家也能一目了然的看出来ImageGetter是干什么的了,就是得到img中src所需的图片!

提醒一点:获取图片以后,一定要设置图片的边界,界线,即:drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());,不然获取图片后,Textview不能显示图片。

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

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

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


下面是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\" / alt="Android中Textview显示带html文本【Textview显示本地图片】_html/css_WEB-ITnose" >";    @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卡里面的图片文件

    //获取本地文件返回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,其实道理是一样的,之前的做法是通过重载方法解析出来图片的路径然后下载图片。只不过是多了一个赋值,没有任何影响。大家有好的思路,也可以介绍下。


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn