Android自动解析html带图片,实现图文混排
不得不先吐槽下项目,后台是 .net 写的,用的webservice,xml传输数据,整的累死。这是一个答题APP,但是居然答题的题目,当初只做了网页版,数据也都是结合网页版做的,现在写APP,给我返回的数据里面都是含html标签的,还带图片,点击之后还能放大看,真是折腾死我。这样一来webview完全不能用啊。
不过我之前记得android有个很暴力的方法,那就是是不是够暴力。但是这远远不够,android里面也没明确表示支持哪些html标签,不过一些文字基础的还是支持的。但TMD,我这带图片啊,怎么搞?在我写这行代码时,发现了这个
ImageGetter有木有?这玩意带个Image是不是对图片也支持,于是我抱着好奇心开始看了起来。
这个方法是这样的:
public static Spanned fromHtml(String source, ImageGetter imageGetter,TagHandler tagHandler)
第一个参数自然是我们的字符串类型的网页数据了比如 "1、找出下图中所有轴对称图形,它们是( )。A、\"http://222.66.2.250:1014//SiteInfo/TextEditor/eWebEditor/uploadfile/2016/06/20160613195331478.png\" border=\"0\" align=\"absmiddle\">" 。
第二个参数 ImageGetter厉害了,果然没错,显示图片的时候需要使用到它,去实现它,然后重写 getDrawable(String source)方法即可
第三个参数 其作用是把 HTML 带标记的文本内容字符串转化成可以显示效果的的 Spanned 字符串 。由于并非所有的 HTML 标签都可以转化,所以在使用时,用户需要自己添加一些必要的标签和处理方法时才会使用的。
说到这,我们就可以上代码直接来写了
布局文件 activity_my_test.xml很简单,放一个textview就可以了
<?xml version="1.0" encoding="utf-8"?>
自定义个 MImageGetter.class 类
public class MImageGetter implements ImageGetter {Context c;TextView container; public MImageGetter(TextView text,Context c) { this.c = c; this.container=text; } public Drawable getDrawable(String source) { final LevelListDrawable drawable = new LevelListDrawable(); Glide.with(c).load(source).asBitmap().into(new SimpleTarget() { @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; }}
这里用了glide类,而且我这里是加载网络图片,如果是本地图片可以试试这个 public Drawable getDrawable(String source) { Drawable drawable = null; InputStream is = null;try {is = c.getResources().getAssets().open(source);} catch (IOException e1) {e1.printStackTrace();} try { TypedValue typedValue = new TypedValue(); typedValue.density = TypedValue.DENSITY_DEFAULT; drawable = Drawable.createFromResourceStream(null, typedValue, is, "src"); DisplayMetrics dm = c.getResources().getDisplayMetrics(); int dwidth = dm.widthPixels-10;//padding left + padding right float dheight = (float)drawable.getIntrinsicHeight()*(float)dwidth/(float)drawable.getIntrinsicWidth(); int dh = (int)(dheight+0.5); int wid = dwidth; int hei = dh; /*int wid = drawable.getIntrinsicWidth() > dwidth? dwidth: drawable.getIntrinsicWidth(); int hei = drawable.getIntrinsicHeight() > dh ? dh: drawable.getIntrinsicHeight();*/ drawable.setBounds(0, 0, wid, hei); return drawable; } catch (Exception e) { System.out.println(e); return null; } }
因为我这个还有点击事件,自定义个 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 { @BindView(R.id.tv) TextView tv; private String content; @Override protected int getContentViewId() { return R.layout.activity_my_test; } @Override protected void initData(Bundle savedInstanceState) { content = "1、找出下图中所有轴对称图形,它们是( )。\n" + "A、\n" + "B、\n" + "C、\n"+ "D、"; 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 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)); }}
下面看一下效果图:
怎么样不错吧,还可以点击图片放大,Intent传递我就不用讲解了,就不列出来了
这里主要是参考
gemgaozhen
这位大神的博客才写出,主要是网上资料太乱,弄了好久才出来,只是希望能帮助大家能解决这个问题。 本人个人原创,如有雷同,纯属巧合,或者与本人联系,做改动。请转载或者CV组合标明出处,谢谢!(如有疑问或错误欢迎指出,本人QQ:752231513)
更多相关文章
- 总结Android(安卓)App内存优化之图片优化
- Android一键压缩Git提交的图片
- RecyclerView的功能扩展(Android图片选择器)
- Android中保存图片的两种方式
- 【整理】Android中使用XML自定义组件各种状态下的背景图片
- Android对View进行截图并保存到本地相册
- Android(安卓)密码校验,字符串中必须包含字母或者数字
- android之图片截取
- Android显示从网络下载图片偏小的问题