public class MyTextViewextends TextView { // 在LinkMovementMethod里有ClickableSpan上发生down事件将被修改为true,发生up事件修改为false public boolean linkHit; publicMyTextView(Context context) { super(context); } publicMyTextView(Context context, AttributeSet attrs) { super(context,attrs); } publicMyTextView(Context context, AttributeSet attrs, intdefStyleAttr) { super(context,attrs, defStyleAttr); } @Override public booleanonTouchEvent(MotionEvent event) { // super的处理方式会始终返回true,导致ListView的item点击不响应, // 此处的处理为如果down或up事件发生在Clickablespan上,将返回true以拦截touch事件,其他时候不拦截 return linkHit; } /** 设置movementMethod,并修改TextView不可点击、长按、获取焦点等 */ public voidsetLocalLinkMovementMethod(LocalLinkMovementMethod movementMethod) { setMovementMethod(movementMethod); // 除非有ClickableSpan被点击,否则不能让TextView拦截ListView的touch事件,此处设置的标志位用处可以查看View.onTouchEvent方法 setFocusable(false); setClickable(false); setLongClickable(false); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { setContextClickable(false); } } } |
/** 判断是否有ClickaSpan被点击,并处理的Touch事件分配 */ public classLocalLinkMovementMethod extends LinkMovementMethod { private staticLocalLinkMovementMethod sInstance; public staticLocalLinkMovementMethod getInstance() { if (sInstance == null) sInstance = newLocalLinkMovementMethod(); return sInstance; } public booleanonTouchEvent(TextView widget, Spannable buffer, MotionEventevent) { int action =event.getAction(); // 参考父类,只判断up和downn事件 if (action ==MotionEvent.ACTION_UP || action ==MotionEvent.ACTION_DOWN) { // 获取手指触摸位置的ClickableSpan ClickableSpan[]link = getOnClickSpan(widget, buffer, event); if (link.length != 0) { // 如果手指触摸位置有ClickableSpan,则down事件拦截Touch事件 if (action ==MotionEvent.ACTION_DOWN) { ((MyTextView)widget).linkHit = true; } else if (action ==MotionEvent.ACTION_UP) { ((MyTextView)widget).linkHit = false; } } } // 交由父类处理点击事件分发。此处的返回值并不影响touch事件的分发,TextView的touch事件只受linkHit影响 return super.onTouchEvent(widget,buffer, event); } /** 参考父类,获取触摸位置的ClickableSpan */ privateClickableSpan[] getOnClickSpan(TextView widget, Spannable buffer,MotionEvent event) { int x = (int)event.getX(); int y = (int)event.getY(); x -=widget.getTotalPaddingLeft(); y -=widget.getTotalPaddingTop(); x +=widget.getScrollX(); y +=widget.getScrollY(); Layout layout =widget.getLayout(); int line =layout.getLineForVertical(y); int off =layout.getOffsetForHorizontal(line, x); returnbuffer.getSpans(off, off, ClickableSpan.class); } } |
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |