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就可以了



    

自定义个 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 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));
    }
}

下面看一下效果图:

Android自动解析html带图片,实现图文混排_第1张图片

怎么样不错吧,还可以点击图片放大,Intent传递我就不用讲解了,就不列出来了



这里主要是参考 

gemgaozhen 

这位大神的博客才写出,主要是网上资料太乱,弄了好久才出来,只是希望能帮助大家能解决这个问题。


本人个人原创,如有雷同,纯属巧合,或者与本人联系,做改动。请转载或者CV组合标明出处,谢谢!(如有疑问或错误欢迎指出,本人QQ:752231513)


你可能感兴趣的:(android)