Android开发在与后台对接的时候,有时会返回HTML5格式的数据,需要解析<p><p/><image></image>标签,比如如下返回数据:
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;">
<span style='color: rgb(0, 0, 0); font-family: 宋体; font-size: 12pt; mso-spacerun: "yes"; mso-font-kerning: 1.0000pt;'><font face="宋体">领导者的综合影响力主要来源于()<span style='font-family: 宋体; font-size: 12pt; font-weight: normal; mso-spacerun: "yes"; mso-font-kerning: 1.0000pt;'><font face="宋体">。</font></span></font></span>
</p>
<p>
<br>
</p>
还有带网络图片的图片的,如:
我们就需要用到富文本来解析了,具体使用如下:
将html代码转换为text,然后显示在textview中呢,有一个简单直接的方法:
textView.setText(Html.fromHtml(content));
用的时候却发现html里面的图片没法被被解析出来,对于图片Html还有一个方法:
public static Spanned fromHtml(String source, ImageGetter imageGetter,TagHandler tagHandler)
这里面需要我们自定义imageGetter,这个对象是用于解析html中的图片.
public class MImageGetter implements Html.ImageGetter {
private Context c;
private TextView container;
public MImageGetter(TextView text, Context c) {
this.c = c;
this.container = text;
}
@Override
public Drawable getDrawable(String source) {
Drawable drawable = null;
InputStream is = null;
//source便是图片的路径,如果图片在本地,可以这样做
is = c.getResources().getAssets().open(source);
try {
TypedValue typedValue = new TypedValue();
typedValue.density = TypedValue.DENSITY_DEFAULT;
drawable = Drawable.createFromResourceStream(null, typedValue, is, "src");
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
System.out.println(e);
return null;
}
}
最终这样调用:
textView.setText(Html.fromHtml(text, new MImageGetter(textView, this), null));
这样便可以实现图文混排了,在该显示图片的地方显示图片。
如果是要显示网络上的图片,getDrawable方法可以这样
public Drawable getDrawable(String source) {
final LevelListDrawable drawable = new LevelListDrawable();
Glide.with(c).load(source).asBitmap().into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource,
GlideAnimation<? super Bitmap> glideAnimation) {
if(resource != null) {
BitmapDrawable bitmapDrawable = new BitmapDrawable(resource);
drawable.addLevel(1, 1, bitmapDrawable);
drawable.setBounds(0, 0, resource.getWidth(),resource.getHeight());
drawable.setLevel(1);
container.invalidate();
container.setText(container.getText());
}
}
});
return drawable;
}
第三个参数 其作用是把 HTML 带标记的文本内容字符串转化成可以显示效果的Spanned 字符串 。由于并非所有的 HTML 标签都可以转化,所以在使用时,用户需要自己添加一些必要的标签和处理方法时才会使用的.
对于Android中有些还要求具有点击事件的功能,就需要自定义个 LinkMovementMethodExt类,那么代码如下:
public class LinkMovementMethodExt extends LinkMovementMethod {
private static LinkMovementMethod sInstance;
private Handler handler = null;
private Class spanClass = null;
public static MovementMethod getInstance(Handler _handler,Class _spanClass) {
if (sInstance == null) {
sInstance = new LinkMovementMethodExt();
((LinkMovementMethodExt)sInstance).handler = _handler;
((LinkMovementMethodExt)sInstance).spanClass = _spanClass;
}
return sInstance;
}
int x1;
int x2;
int y1;
int y2;
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (event.getAction() == MotionEvent.ACTION_DOWN){
x1 = (int) event.getX();
y1 = (int) event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
x2 = (int) event.getX();
y2 = (int) event.getY();
if (Math.abs(x1 - x2) < 10 && Math.abs(y1 - y2) < 10) {
x2 -= widget.getTotalPaddingLeft();
y2 -= widget.getTotalPaddingTop();
x2 += widget.getScrollX();
y2 += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y2);
int off = layout.getOffsetForHorizontal(line, x2);
/**
* get you interest span
*/
Object[] spans = buffer.getSpans(off, off, spanClass);
if (spans.length != 0) {
Selection.setSelection(buffer,
buffer.getSpanStart(spans[0]),
buffer.getSpanEnd(spans[0]));
MessageSpan obj = new MessageSpan();
obj.setObj(spans);
obj.setView(widget);
Message message = handler.obtainMessage();
message.obj = obj;
message.what = 200;
message.sendToTarget();
return true;
}
}
}
//return false;
return super.onTouchEvent(widget, buffer, event);
}
public boolean canSelectArbitrarily() {
return true;
}
public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
KeyEvent event) {
return false;
}
MessageSpan类如下:
public class MessageSpan {
private Object obj;
private TextView view;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public TextView getView() {
return view;
}
public void setView(TextView view) {
this.view = view;
}
}
页面及使用代码如下:
public class MyTestActivity extends BaseActivity {
TextView tv;
private String content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_test);
tv = findViewById(R.id.tv);
}
@Override
protected void initData(Bundle savedInstanceState) {
content = "1、找出下图中所有轴对称图形,它们是( )。\n" +
"A、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195331478.png\" border=\"0\" align=\"absmiddle\">\n" +
"B、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195406586.png\" border=\"0\" align=\"absmiddle\">\n" +
"C、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195417277.png\" border=\"0\" align=\"absmiddle\">\n"+
"D、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195426887.png\" border=\"0\" align=\"absmiddle\">";
tv.setText(Html.fromHtml(content, new MImageGetter(tv, getApplicationContext()), null));
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int what = msg.what;
if (what == 200) {
MessageSpan ms = (MessageSpan) msg.obj;
Object[] spans = (Object[]) ms.getObj();
final ArrayList<String> list = new ArrayList<>();
for (Object span : spans) {
if (span instanceof ImageSpan) {
Log.i("picUrl==", ((ImageSpan) span).getSource());
list.add(((ImageSpan) span).getSource());
Intent intent = new Intent(getApplicationContext(), ImageGalleryActivity.class);
intent.putStringArrayListExtra("images", list);
startActivity(intent);
}
}
}
}
};
tv.setMovementMethod(LinkMovementMethodExt.getInstance(handler, ImageSpan.class));
}
}