业务场景: 在微信聊天窗口中需要显示文字图片和超链接时。
问题所在: 一般TextView只能显示
解决方案:
1、普通方式只能显示文本内容。
2、 Html.fromHtml(html)只能显示html和超链接,图片不能显示。
3、 Html.fromHtml+ImageGetter+URLSpan。(即能实现html,又能实现超链接和图片的显示)
实现过程:
需要以下三个类:
1、从网络获取图片的类:NetImageGetter
package utils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.os.AsyncTask;
import android.text.Html;
import android.widget.TextView;
/**
* des:textView用于加载远端图片
*
* @author Administrator
*
*/
public class NetImageGetter implements Html.ImageGetter {
private Context context;
private TextView contentTextView;
private int width=0;
public NetImageGetter(Context context,TextView contentTextView,int width)
{
this.context=context;
this.contentTextView=contentTextView;
this.width=width;
}
@Override
public Drawable getDrawable(String source) {
LevelListDrawable d = new LevelListDrawable();
d.setBounds(0, 0, 300, 200);
new LoadImage().execute(source, d);
return d;
}
/**
* 异步下载图片类
*
* @author Ruffian
* @date 2016年1月15日
*
*/
class LoadImage extends AsyncTask
private LevelListDrawable mDrawable;
@Override
protected Bitmap doInBackground(Object... params) {
String source = (String) params[0];
mDrawable = (LevelListDrawable) params[1];
try {
InputStream is = new URL(source).openStream();
return BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 图片下载完成后执行
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
BitmapDrawable d = new BitmapDrawable(bitmap);
mDrawable.addLevel(1, 1, d);
mDrawable = getDrawableAdapter(context, mDrawable,
bitmap.getWidth(), bitmap.getHeight());
// mDrawable.setBounds(0, 0, bitmap.getWidth(),
// bitmap.getHeight());
mDrawable.setLevel(1);
contentTextView.invalidate();
CharSequence t = contentTextView.getText();
contentTextView.setText(t);
}
}
public LevelListDrawable getDrawableAdapter(Context context,
LevelListDrawable drawable, int oldWidth, int oldHeight) {
LevelListDrawable newDrawable = drawable;
long newHeight = 0;// 未知数
int newWidth = width;// 默认屏幕宽
newHeight = (newWidth * oldHeight) / oldWidth;
newDrawable.setBounds(0, 0, newWidth, (int) newHeight);
return newDrawable;
}
}
}
2、给TextView内html加入超链接点击事件的类:MyURLSpan
/**
* 加入超链接处理
* @author Administrator
*
*/
private static class MyURLSpan extends ClickableSpan {
private String mUrl;
private Context mContext;
MyURLSpan(String url, Context context) {
mContext = context;
mUrl = url;
}
@Override
public void onClick(View widget) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(mUrl);
intent.setData(content_url);
intent.setClassName("com.android.browser",
"com.android.browser.BrowserActivity");
this.mContext.startActivity(intent);
}
}
3、实现显示带图片和超链接的html到TextView中的类:
package utils;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;
public class TextViewUtil {
/**
* des:设置html到textview中
*
* @param contentView
* @param html
* @param width
* 图片显示区域宽度,根据不同情况显示不同大小
*/
public static void setHtmlToTextView(Context context, TextView contentView,
String html, int width) {
NetImageGetter netImageGetter = new NetImageGetter(context,
contentView, width);
Spanned text = Html.fromHtml(html, netImageGetter, null);
contentView.setMovementMethod(LinkMovementMethod.getInstance());
contentView.setText(text);
CharSequence charSequence = contentView.getText();
if (charSequence instanceof Spannable) {
int end = text.length();
Spannable sp = (Spannable) contentView.getText();
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
for (URLSpan url : urls) {
MyURLSpan myURLSpan = new MyURLSpan(url.getURL(), context);
style.setSpan(myURLSpan, sp.getSpanStart(url),
sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
contentView.setText(style);
}
}
/**
* 加入超链接处理
* @author Administrator
*
*/
private static class MyURLSpan extends ClickableSpan {
private String mUrl;
private Context mContext;
MyURLSpan(String url, Context context) {
mContext = context;
mUrl = url;
}
@Override
public void onClick(View widget) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(mUrl);
intent.setData(content_url);
intent.setClassName("com.android.browser",
"com.android.browser.BrowserActivity");
this.mContext.startActivity(intent);
}
}
}