Android 图文混排(三)TextView图片点击

整体思路

在Html.forHtml中已经将html内容中的超链接和图片转义成为 UrlSpan 和 ImageSpan,进而在 TextView 中完成显示。

但是有些需求仅仅有展示是不够的,还需要用户交互。Android 提供了 LinkMovementMethod 类以实现了对于文本内容中超链接的遍历,并且支持对于超链接的点击事件。在 TextView 中我们调用 textView.setMovementMethod(LinkMovementMethod.getInstance()) 方法。就可以使点击 UrlSpan 能够触发打开链接的功能。

仅仅支持打开链接的方法是不够的,我们还需要添加ImageSpan 的点击事件,这里我们可以在触发 UrlSpan 的基础上,添加对 ImageSpan 的支持。

1、我们先定义一个类来继承LinkMovementMethod,并且重写方法 onTouchEvent, 将 ImageSpan 的类型传入。

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;
}

2、点击图片向 Handler 传递 Message。(加上图片滑动的过滤,这样就不会影响下滑阅读)

int x1;
int x2;
int y1;
int y2;
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
    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 super.onTouchEvent(widget, buffer, event);
}

3、处理点击事件

// make links and image work
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();
            for (Object span : spans) {
                if (span instanceof ImageSpan) {
                    Log.d(TAG, "点击了图片"+((ImageSpan) span).getSource());
                    //处理自己的逻辑
                }
            }
        }
    }
};
setMovementMethod(LinkMovementMethodExt.getInstance(handler, ImageSpan.class));

MessageSpan.java

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;
   }
}

控制台打印

Paste_Image.png

如有什么不对或者不规范的地方请留言或私信我,非常感谢

传送门:
1、Android 图文混排(一) TextView实现图文显示
2、Android 图文混排(二) EditText实现图文显示
3、Android 图文混排(三)TextView图片点击

参考文章:
1、http://www.ibm.com/developerworks/cn/web/1407_zhangqian_androidhtml/

你可能感兴趣的:(Android 图文混排(三)TextView图片点击)