android显示html中图片不显示,android中html显示和图片异步加载

写了快大半年android了,发现写的博客数量太少了。很多东西其实都可以总结记录一下的,哎,只怪太懒,难得今天这么休闲,就一口气了。其实这篇文章介绍的主题也是今天才搞定的,初衷是,服务端发送富文本标签到客户端可以显示,TextView本来是可以显示图片的,比如微信中插入图片类似,问题是什么呢,图片异步加载的实现方式,客户端想做到用户体验非常爽需要花费大量功夫处理。废话多了就啰嗦了,写了一个自己比较好用的类,先演示使用方法吧,想用的人是不关心你的实现。

TextView htmlTextView = (TextView)findViewById(R.id.text_view);

Spanned sp = Html.fromHtml(content,

new HtmlImageGetter(htmlTextView, "/esun_msg", _defaultLoading),

null);

htmlTextView.setText(sp);

介绍一下HtmlImageGetter析构中的三个参数,第一个是Textview对象,主要是为了加载完成后刷新才能显示图片用,第二个参数是,加载出来的图片保存到sd卡的目录,第三个参数是图片未加载时候先显示的加载中Drawable对象。怎么样,用起来还算ok吧,因为图快速实现,所以几乎都忽略了注释,下面就直接来类了

public class HtmlImageGetter implements Html.ImageGetter{

private TextView _htmlText;

private String _imgPath;

private Drawable _defaultDrawable;

public HtmlImageGetter(TextView htmlText, String imgPath, Drawable defaultDrawable){

_htmlText = htmlText;

_imgPath = imgPath;

_defaultDrawable = defaultDrawable;

}

@Override

public Drawable getDrawable(String imgUrl) {

String imgKey = Common.md5(imgUrl);

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{

Common.log("load img:"+imgKey+":null");

}

}

URLDrawable urlDrawable = new URLDrawable(_defaultDrawable);

new AsyncThread(urlDrawable).execute(imgKey, imgUrl);

return urlDrawable;

}

private class AsyncThread extends AsyncTask{

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);

}

}

}

在代码中有两个封装的方法,一个是网络请求图片和保存图片到sd卡中,就简单贴贴代码了,没甚么技术含量

public class 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, HashMappropertys){

return getHttpData(baseUrl, "POST", reqData, propertys);

}

/**

* 获取赛事信息

* @return

*/

public static String getHttpData(String baseUrl, String method, String reqData, HashMappropertys){

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(Config.TIME_OUT);

if(propertys != null && !propertys.isEmpty()){

Iterator> props = propertys.entrySet().iterator();

Map.Entryentry;

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.d(Config.LOG_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){

Common.errorReport(ex);

}catch (IOException ex){

Common.errorReport(ex);

}finally{

if(reader !=null && urlConn!=null){

try {

outWrite.close();

inpStream.close();

reader.close();

urlConn.disconnect();

} catch (IOException ex) {

Common.errorReport(ex);

}

}

}

Log.d(Config.LOG_TAG, "[Http data]["+baseUrl+"]:" + data);

return data;

}

/**

* 获取Image信息

* @return

*/

public static Bitmap getBitmapData(String imgUrl){

Bitmap bmp = null;

Log.d(Config.LOG_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){

Common.errorReport(ex);

}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(Config.LOG_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){

Common.errorReport(ex);

}finally{

if(inpStream !=null){

try {

inpStream.close();

} catch (IOException ex) {

ex.printStackTrace();

}

}

}

return inpStream;

}

}

package com.esun.trade.lib;

import java.io.*;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.os.Environment;

import android.util.Log;

import com.esun.trade.inc.Config;

public class FileUtil {

private static int FILE_SIZE = 4*1024;

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(Config.LOG_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(Config.LOG_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) {

Common.errorReport(ex);

return null;

}finally{

try{

if(outSm != null) outSm.close();

}catch (IOException ex) {

Common.errorReport(ex);

}

}

Common.log("[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){

Common.errorReport(ex);

}

return null;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、[Android实例]实现TextView里的文字有不同颜色 转eoe:http://www.eoeandroid.com/thread-4496-1-1.html import android.text.Html; TextView t3 = (TextView) findViewById(R.id.text3); t3.setText( Html.fromHtml( "<b>text3:</b> Text with a " + "<a href=\"http://www.google.com\">link</a> " + "created in the Java source code using HTML.")); 二、TextView显示html文件图片 转javaeye:http://da-en.javaeye.com/blog/712415 我们知道要让TextView解析和显示Html代码。可以使用 Spanned text = Html.fromHtml(source); tv.setText(text); 来实现,这个用起来简单方便。 但是,怎样让TextView也显示Html<image>节点的图像呢? 我们可以看到fromHtml还有另一个重构: fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) 实现一下ImageGetter就可以让图片显示了: ImageGetter imgGetter = new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { Drawable drawable = null; drawable = Drawable.createFromPath(source); // Or fetch it from the URL // Important drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable .getIntrinsicHeight()); return drawable; } }; 至于TagHandler,我们这里不需要使用,可以直接传null。 参考文档: http://tech-droid.blogspot.com/2010/06/textview-with-html-content.html英语好的朋友就直接看英文文档吧。 三、Android---文字插入表情 转自:http://blog.163.com/spf9190@126/blog/static/50207531201091545954587/ 这段时间在做一个短信项目,需要实现短信插入表情的功能,本一位非常困难,经过一段时间的研究,发现还是比较簡単的,现在总结如下。 以短信输入框为例,短信的输入框是一个EditText,它的append方法不仅可以入字符串,还可以添HTML标记。以下就是使用HTML标记添表情的具体操作。 首先需要构建一个ImageGetter,作用是通过HTML标记获得对应在res目录下的图片: ImageGetter imageGetter = new ImageGetter() { @Override public Drawable getDrawable(String source) { int id = Integer.parseInt(source); //根据id从资源文件获取图片对象 Drawable d = getResources().getDrawable(id); d.setBounds(0, 0, d.getIntrinsicWidth(),d.getIntrinsicHeight()); return d; } }; 然后就可以直接往EditText视图 inputLable.append(Html.fromHtml("<img src='"+clickedImageId+"'/>", imageGetter, null)); 其 Html.fromHtml("<img src='"+clickedImageId+"'/>"就是HTML图片标记,在Android支持了部分HTML标记的使用(这方面我还在继续研究),HTML标记必须被Html.fromHtml修饰。imageGetter即为之前创建的ImageGetter类型的对象。
要在 ListView 显示多张图片,可以使用 OkHttp 进行网络请求获取图片,并使用 ViewHolder 模式对 ListView 进行优化,以提高列表的滑动流畅性。具体实现步骤如下: 1. 在 Adapter 定义 ViewHolder,用于缓存 item 的控件: ```java private static class ViewHolder { ImageView imageView; } ``` 2. 在 getView() 方法获取 ViewHolder,如果 convertView 为 null,则新建一个 ViewHolder,并使用 LayoutInflater 布局文件: ```java @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false); holder = new ViewHolder(); holder.imageView = convertView.findViewById(R.id.image_view); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 图片并设置到 ImageView loadImage(holder.imageView, imageUrlList.get(position)); return convertView; } ``` 3. 在 loadImage() 方法使用 OkHttp 进行网络请求,获取图片并设置到 ImageView : ```java private void loadImage(final ImageView imageView, String imageUrl) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(imageUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream inputStream = response.body().byteStream(); final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); mHandler.post(new Runnable() { @Override public void run() { imageView.setImageBitmap(bitmap); } }); } }); } ``` 其,`imageUrlList` 是存储图片 URL 地址的列表,`mContext` 是 Context 对象,`mHandler` 是 Handler 对象,用于在子线程更新 UI。首先创建一个 OkHttpClient 对象,然后使用 Request.Builder 构建一个请求,设置请求的 URL 地址。接着使用 `newCall(request).enqueue()` 方法异步执行请求,并在回调方法获取响应的结果,将 InputStream 转换成 Bitmap,并使用 Handler 将 Bitmap 设置到 ImageView ,以更新 UI。 需要注意的是,由于网络请求是异步执行的,因此需要使用 Handler 来更新 UI,否则会出现异常。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值