Android实现TextView显示HTML加图片的方法

本文实例讲述了Android实现TextView显示HTML加图片的方法。分享给大家供大家参考,具体如下:

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

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

此处有作部分修改,代码独立。图片实现异步加载。解决上述问题
用法,调用代码activity

//TextView 控件
textViewContent = (TextView) getActivity().findViewById(R.id.textview_prodcut_detail_more_zp_content);
//HTML文本
zp_content = "测试图片信息:<br><img src=\"http://b2c.zeeeda.com/upload/2013/05/10/136814766742544.jpg\" />";
//默认图片,无图片或没加载完显示此图片
Drawable defaultDrawable = MainActivity.ma.getResources().getDrawable(R.drawable.stub);
//调用
Spanned sp = Html.fromHtml(zp_content, new HtmlImageGetter(textViewContent, "/esun_msg", defaultDrawable), null);
textViewContent.setText(sp);

HtmlImageGetter类:

import java.io.InputStream;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.Html.ImageGetter;
import android.util.Log;
import android.widget.TextView;
public class HtmlImageGetter implements ImageGetter{
  private TextView _htmlText;
  private String _imgPath;
  private Drawable _defaultDrawable;
  private String TAG = "HtmlImageGetter";
  public HtmlImageGetter(TextView htmlText, String imgPath, Drawable defaultDrawable){
    _htmlText = htmlText;
    _imgPath = imgPath;
    _defaultDrawable = defaultDrawable;
  }
  @Override
  public Drawable getDrawable(String imgUrl) {
    String imgKey = String.valueOf(imgUrl.hashCode());
    String path = Environment.getExternalStorageDirectory() + _imgPath;
    FileUtil.createPath(path);
    String[] ss = imgUrl.split("\\.");
    String imgX = ss[ss.length-1];
    imgKey = path+"/" + imgKey+"."+imgX;
    if(FileUtil.exists(imgKey)){
      Drawable drawable = FileUtil.getImageDrawable(imgKey);
      if(drawable != null){
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        return drawable;
      }else{
        Log.v(TAG,"load img:"+imgKey+":null");
      }
    }
    URLDrawable urlDrawable = new URLDrawable(_defaultDrawable);
    new AsyncThread(urlDrawable).execute(imgKey, imgUrl);
    return urlDrawable;
  }
  private class AsyncThread extends AsyncTask<String, Integer, Drawable> {
    private String imgKey;
    private URLDrawable _drawable;
    public AsyncThread(URLDrawable drawable){
      _drawable = drawable;
    }
    @Override
    protected Drawable doInBackground(String... strings) {
      imgKey = strings[0];
      InputStream inps = NetWork.getInputStream(strings[1]);
      if(inps == null) return _drawable;
      FileUtil.saveFile(imgKey, inps);
      Drawable drawable = Drawable.createFromPath(imgKey);
      return drawable;
    }
    public void onProgressUpdate(Integer... value) {
    }
    @Override
    protected void onPostExecute(Drawable result) {
      _drawable.setDrawable(result);
      _htmlText.setText(_htmlText.getText());
    }
  }
  public class URLDrawable extends BitmapDrawable {
    private Drawable drawable;
    public URLDrawable(Drawable defaultDraw){
      setDrawable(defaultDraw);
    }
    private void setDrawable(Drawable ndrawable){
      drawable = ndrawable;
      drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
          .getIntrinsicHeight());
      setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
          .getIntrinsicHeight());
    }
    @Override
    public void draw(Canvas canvas) {
      drawable.draw(canvas);
    }
  }
}

NetWork 类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
public class NetWork {
  private static String TAG = "NetWork";
  public static String getHttpData(String baseUrl){
    return getHttpData(baseUrl, "GET", "", null);
  }
  public static String postHttpData(String baseUrl, String reqData){
    return getHttpData(baseUrl, "POST", reqData, null);
  }
  public static String postHttpData(String baseUrl, String reqData, HashMap<String, String> propertys){
    return getHttpData(baseUrl, "POST", reqData, propertys);
  }
  /**
   * 获取赛事信息
   * @return
   */
  public static String getHttpData(String baseUrl, String method, String reqData, HashMap<String, String> propertys){
    String data = "", str;
    PrintWriter outWrite = null;
    InputStream inpStream = null;
    BufferedReader reader = null;
    HttpURLConnection urlConn = null;
    try{
      URL url = new URL(baseUrl);
      urlConn = (HttpURLConnection)url.openConnection();
      //启用gzip压缩
      urlConn.addRequestProperty("Accept-Encoding", "gzip, deflate");
      urlConn.setRequestMethod(method);
      urlConn.setDoOutput(true);
      urlConn.setConnectTimeout(3000);
      if(propertys != null && !propertys.isEmpty()){
        Iterator<Map.Entry<String, String>> props = propertys.entrySet().iterator();
        Map.Entry<String, String> entry;
        while (props.hasNext()){
          entry = props.next();
          urlConn.setRequestProperty(entry.getKey(), entry.getValue());
        }
      }
      outWrite = new PrintWriter(urlConn.getOutputStream());
      outWrite.print(reqData);
      outWrite.flush();
      urlConn.connect();
      //获取数据流
      inpStream = urlConn.getInputStream();
      String encode = urlConn.getHeaderField("Content-Encoding");
      //如果通过gzip
      if(encode !=null && encode.indexOf("gzip") != -1){
        Log.v(TAG, "get data :" + encode);
        inpStream = new GZIPInputStream(inpStream);
      }else if(encode != null && encode.indexOf("deflate") != -1){
        inpStream = new InflaterInputStream(inpStream);
      }
      reader = new BufferedReader(new InputStreamReader(inpStream));
      while((str = reader.readLine()) != null){
        data += str;
      }
    }catch (MalformedURLException ex){
      ex.printStackTrace();
    }catch (IOException ex){
      ex.printStackTrace();
    }finally{
      if(reader !=null && urlConn!=null){
        try {
          outWrite.close();
          inpStream.close();
          reader.close();
          urlConn.disconnect();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    Log.d(TAG, "[Http data]["+baseUrl+"]:" + data);
    return data;
  }
  /**
   * 获取Image信息
   * @return
   */
  public static Bitmap getBitmapData(String imgUrl){
    Bitmap bmp = null;
    Log.d(TAG, "get imgage:"+imgUrl);
    InputStream inpStream = null;
    try{
      HttpGet http = new HttpGet(imgUrl);
      HttpClient client = new DefaultHttpClient();
      HttpResponse response = (HttpResponse)client.execute(http);
      HttpEntity httpEntity = response.getEntity();
      BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
      //获取数据流
      inpStream = bufferedHttpEntity.getContent();
      bmp = BitmapFactory.decodeStream(inpStream);
    }catch (Exception ex){
      ex.printStackTrace();
    }finally{
      if(inpStream !=null){
        try {
          inpStream.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    return bmp;
  }
  /**
   * 获取url的InputStream
   * @param urlStr
   * @return
   */
  public static InputStream getInputStream(String urlStr){
    Log.d(TAG, "get http input:"+urlStr);
    InputStream inpStream = null;
    try{
      HttpGet http = new HttpGet(urlStr);
      HttpClient client = new DefaultHttpClient();
      HttpResponse response = (HttpResponse)client.execute(http);
      HttpEntity httpEntity = response.getEntity();
      BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
      //获取数据流
      inpStream = bufferedHttpEntity.getContent();
    }catch (Exception ex){
      ex.printStackTrace();
    }finally{
      if(inpStream !=null){
        try {
          inpStream.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    return inpStream;
  }
}

FileUtil类:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;
public class FileUtil {
  private static int FILE_SIZE = 4*1024;
  private static String TAG = "FileUtil";
  public static boolean hasSdcard(){
    String status = Environment.getExternalStorageState();
    if(status.equals(Environment.MEDIA_MOUNTED)){
      return true;
    }
    return false;
  }
  public static boolean createPath(String path){
    File f = new File(path);
    if(!f.exists()){
      Boolean o = f.mkdirs();
      Log.i(TAG, "create dir:"+path+":"+o.toString());
      return o;
    }
    return true;
  }
  public static boolean exists(String file){
    return new File(file).exists();
  }
  public static File saveFile(String file, InputStream inputStream){
    File f = null;
    OutputStream outSm = null;
    try{
      f = new File(file);
      String path = f.getParent();
      if(!createPath(path)){
        Log.e(TAG, "can't create dir:"+path);
        return null;
      }
      if(!f.exists()){
        f.createNewFile();
      }
      outSm = new FileOutputStream(f);
      byte[] buffer = new byte[FILE_SIZE];
      while((inputStream.read(buffer)) != -1){
        outSm.write(buffer);
      }
      outSm.flush();
    }catch (IOException ex) {
      ex.printStackTrace();
      return null;
    }finally{
      try{
        if(outSm != null) outSm.close();
      }catch (IOException ex) {
        ex.printStackTrace();
      }
    }
    Log.v(TAG,"[FileUtil]save file:"+file+":"+Boolean.toString(f.exists()));
    return f;
  }
  public static Drawable getImageDrawable(String file){
    if(!exists(file)) return null;
    try{
      InputStream inp = new FileInputStream(new File(file));
      return BitmapDrawable.createFromStream(inp, "img");
    }catch (Exception ex){
      ex.printStackTrace();
    }
    return null;
  }
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》、《Android文件操作技巧汇总》、《Android操作SQLite数据库技巧总结》、《Android操作json格式数据技巧总结》、《Android数据库操作技巧总结》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • Android的TextView与Html相结合的具体方法

    Android中的TextView,本身就支持部分的Html格式标签.这其中包括常用的字体大小颜色设置,文本链接等.使用起来也比较方便,只需要使用Html类转换一下即可.比如:textView.setText(Html.fromHtml(str));一.实现TextView里的文字有不同颜色[plain] 复制代码 代码如下: import android.text.Html; TextView t3 = (TextView) findViewById(R.id.text3);    t3.se

  • android textview 显示html方法解析

    现在网络的繁盛时代,光文字是不能满足人们的胃口的,图片,flash,音频,视频就成为浏览网页的主流显示,在手机上也一样.在手机上显示从网络端获取的数据显示,大家很自然的想起两种方式,一种就是webview,一种就是TextView.当然webView直接显示html页面就行了,我主要说的TextView显示html内容. 首先,说下TextView到底支持那些标签呢,通过对源码的查看,发现Textview可以解析一部分html标签,如: 复制代码 代码如下: <a href="...&qu

  • Android TextView显示Html类解析的网页和图片及自定义标签用法示例

    本文实例讲述了Android TextView显示Html类解析的网页和图片及自定义标签.分享给大家供大家参考,具体如下: Android系统显示HTML网页的最佳控件为WebView,有时候为了满足特定需求,需要在TextView中显示HTML网页.图片及解析自定义标签. 1.TextView显示Html类解析的网页 CharSequence richText = Html.fromHtml("<strong>萝卜白菜的博客</strong>--<a href='

  • 通过Html网页调用本地安卓(android)app程序代码

    一.通过html页面打开Android本地的app 1.首先在编写一个简单的html页面 复制代码 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a h

  • Android编程获取网址HTML代码的方法

    本文实例讲述了Android编程获取网址HTML代码的方法.分享给大家供大家参考,具体如下: /** * * @param aUrl 网址 * @param aEncode 编码 * @return 返回的HTML代码 * @throws Exception 对外抛出异常 */ public String getHTML(String aUrl, String aEncode) throws Exception { URL url = new URL(aUrl); HttpURLConnecti

  • Android UI使用HTML布局方法实例

    很多时候我们用HTML布局会更方便直接,记录一下. 我现在主要是直接调用服务器的网页(实际上是jsp的,只是返回的是html),所以需要联网,第一步添加权限. 复制代码 代码如下: <uses-permission android:name="android.permission.INTERNET" /> 布局文件直接用一个WebView,如下: 复制代码 代码如下: <?xml version="1.0" encoding="utf-8

  • android教程之textview解析带图片的html示例

    复制代码 代码如下: public class MainActivity extends Activity { private Handler handler; private String html; private TextView tv; private ProgressBar bar; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  s

  • Android TextView显示html样式的文字

    先给大家说下项目需求: TextView显示一段文字,格式为:白雪公主(姓名,字数不确定)向您发来了2(消息个数,不确定)条消息 这段文字中名字和数字的长度是不确定的,还要求名字和数字各自有各自的颜色. 就想到了用 Html.fromHtml(String str)来实现. 看方法名很简单,就是可以显示字符串str对应的html格式的文本 比如: Html.fromHtml(<font color='red' size='24'>你好</font>" ) 就将你好以htm

  • Android开发之利用jsoup解析HTML页面的方法

    本文实例讲述了Android利用jsoup解析HTML页面的方法.分享给大家供大家参考,具体如下: 这节主要是讲解jsoup解析HTML页面.由于在android开发过程中,不可避免的涉及到web页面的抓取,解析,展示等等,所以,在这里我主要展示下利用jsoup jar包来抓取cnbeta.com网站的话题分类的实例. 下面是主要的代码,由于使用及其简单,我这里就不再多说了: package com.android.web; import java.io.BufferedInputStream;

  • 如何在android中使用html作布局文件

    在android开发中,通常使用xml格式来描述布局文件.就目前而言,熟悉android布局及美化的人员少之又少,出现了严重的断层.大部分企业,其实还是程序员自己动手布局.这样既浪费时间和精力,也未必能达到理想的效果.但是,在企业级的android开发中,使用html页面进行布局,也有很多的优势(例如:简单,大部分开发人员及美工都熟悉,方便统一进行更新,管理).据笔者了解,已经有不少的公司在使用这种方式进行布局开发.这也可能是一种趋势. 下面,我将给出一个实例代码,供大家学习使用html页面给a

随机推荐