Textview能够显示基本的HTML标签java
<a href="..."> <b> <big> <blockquote> <br> <cite> <dfn> <div align="..."> <em> <font size="..." color="..." face="..."> <h1> <h2> <h3> <h4> <h5> <h6> <i> <img src="..."> <p> <small> <strike> <strong> <sub> <sup> <tt> <u>
下面着重说一下Textview显示“img”标签,也许看到这里,你们都会想到就是构建ImageGetter,重载一下其 public Drawable getDrawable(String source)方法,获取该路径的图片。android
例如:网络
final Html.ImageGetter imageGetter = new Html.ImageGetter() { public Drawable getDrawable(String source) { return drawable; }; };
下面来讲下public Drawable getDrawable(String source)这个方法,source就是图片路径!异步
例如:ide
final String sText = "测试图片信息:<br><img src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" /><img src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" />"; tView.setText(Html.fromHtml(sText, imageGetter, null));
则source就是img的src的值,既是:http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg这个图片路径测试
固然这个<img src=路径/> 这个路径既能够是网络图片,也能够本地图片,项目资源图片url
例如:本地图片<img src=\""/sdcard/images/test.jpg"\"/> 项目资源图片 <img src=\""+R.drawable.market_none_image+"\"/>spa
可是不一样的路径,ImageGetter的重载处理方法都不同,下面来一一介绍各类的处理方式.线程
第一种:本地图片code
final String sText2 = "测试图片信息:<img src=\"/mnt/sdcard/temp/1.jpg\" />"; 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+"\" />";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\" />"; 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\" />"; @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,其实道理是同样的,以前的作法是经过重载方法解析出来图片的路径而后下载图片。只不过是多了一个赋值,没有任何影响。你们有好的思路,也能够介绍下。