package com.kaikeba.android.course.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Base64;
import android.util.Log;
import android.widget.TextView;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* 富文本显示
* https://www.kaelli.com/21.html
*/
public class RichTextUtils {
private static final String TAG = "RichTextUtils >>> ";
/**
* 显示富文本
*
* @param textView textView
* @param richText 富文本
*/
public static void showRichHtmlWithImageName(TextView textView, String richText) {
/*
* 加载图片,html中img src为drawable中图片名称
* 例如:"<strong>我的测试</strong><img src=\"photo.png\">"
*/
Html.ImageGetter imageGetter = new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Log.d(TAG, "[showRichHtmlWithImageName] source is " + source);
if (source == null) {
return null;
}
String resName = source.split("\\.")[0];
Log.d(TAG, " resName is " + resName);
Drawable drawable = getDrawableByName(textView.getContext(), resName);
if (drawable != null) {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
return drawable;
}
};
/* 富文本内容转换为CharSequence */
CharSequence charSequence = Html.fromHtml(richText, imageGetter, null);
/* 设置TextView内容 */
if (textView != null) {
textView.setText(charSequence);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
Log.d(TAG, "[showRichHtmlWithImageName] charSequence is " + charSequence);
}
/**
* 显示富文本
*
* @param textView textView
* @param richText 富文本
*/
public static void showRichHtmlWithImageUrl(TextView textView, final String richText) {
final MyHander myHander = new MyHander(textView);
/* 由于需从网络中获取图片内容,故需开线程处理 */
new Thread(new Runnable() {
@Override
public void run() {
/*
* 显示网络图片
* 例如:"<strong>我的测试</strong><img src=\"http://www.test.cn/2111111/0\">"
*/
Html.ImageGetter imageGetter = new Html.ImageGetter() {
@Override
public Drawable getDrawable(final String source) {
Log.d(TAG, "[showRichTextWithImageUrl] source is " + source);
if (source == null) {
return null;
}
Drawable drawable = null;
drawable = getUrlDrawable(textView.getContext(), source);
return drawable;
}
};
CharSequence charSequence = Html.fromHtml(richText, imageGetter, null);
/* 发送消息 */
Message message = new Message();
message.what = 1;
message.obj = charSequence;
myHander.sendMessage(message);
}
}).start();
}
/**
* 显示富文本
*
* @param textView textView
* @param richText 富文本
*/
public static void showRichHtmlWithImageContent(final TextView textView, final String richText) {
final MyHander myHander = new MyHander(textView);
new Thread() {
public void run() {
/*
* 显示本地图片,Data URI scheme方式
* 例如:<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAA......
* url:src=\"https"
*/
Html.ImageGetter imageGetter = new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Log.d(TAG, "[showRichHtmlWithContent] source is " + source);
if (source == null) {
return null;
}
Drawable drawable = null;
if (checkIsUrl(source)) {//判断是url
drawable = getUrlDrawable(textView.getContext(), source);
} else {
/* 获取图片base64编码的字符串 */
int index = source.indexOf("base64,") + 7;
String imageContent = source.substring(index);
Log.d(TAG, "imageContent length is " + imageContent.length());
/* 将图片base64编码字符串转换成drawable */
Bitmap bitmap = stringToBitmap(imageContent);
drawable = new BitmapDrawable(textView.getContext().getResources(), bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
return drawable;
}
};
CharSequence charSequence = Html.fromHtml(richText, imageGetter, null);
Log.d(TAG, "imageContent richText is " + richText);
/* 发送消息 */
Message message = new Message();
message.what = 1;
message.obj = charSequence;
myHander.sendMessage(message);
}
}.start();
}
/**
* 检查是否是Url
*
* @param source 字符串
*/
private static boolean checkIsUrl(String source) {
try {
Log.d(TAG, "checkIsUrl" + source);
URL url = new URL(source);
if (url.getHost() != null) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
/**
* 通过Url获取Drawable
*
* @param source URL地址
*/
private static Drawable getUrlDrawable(Context c, String source) {
Drawable drawable = null;
try {
URL url = new URL(source);
InputStream is = url.openStream();
Log.d(TAG, "is is " + is.toString());
Bitmap bitmap = BitmapFactory.decodeStream(is);
drawable = new BitmapDrawable(c.getResources(), bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static class MyHander extends Handler {
TextView textView;
MyHander(TextView textView) {
this.textView = textView;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
if (textView != null) {
textView.setText((CharSequence) msg.obj);
}
}
}
}
/**
* 根据资源名获取图片ID
*/
private static Drawable getDrawableByName(Context context, String resName) {
if (context == null) {
return null;
}
int resId = context.getResources().getIdentifier(resName, "drawable", context.getPackageName());
if (resId == 0) {
return null;
}
return context.getResources().getDrawable(resId);
}
/**
* 将base64字符串转换成Bitmap类型
*
* @param content base64字符串
* @return Bitmap
*/
private static Bitmap stringToBitmap(String content) {
byte[] bitmapArray = Base64.decode(content, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
}
/**
* 将Bitmap转换成base64字符串
*
* @param bitmap Bitmap
* @return base64字符串
*/
private static String bitmapToString(Bitmap bitmap) {
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bStream);
byte[] bytes = bStream.toByteArray();
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
}