zoukankan      html  css  js  c++  java
  • [Android]解决ClickableSpan中点击后ListView中item的长按冲突的问题

    以下内容为原创,转载请注明:

    来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3823429.html

    项目中碰到一个问题,情景是这样的:

    有一个ListView,每个item中有一个TextView,这个TextView实现了LongClick事件,这个TextView中又添加了ClickableSpan,实现了方法onClick。

    我的需求是点击ClickableSpan,则响应ClickableSpan事件;长按ClickableSpan效果跟长按TextView应该一样,都响应TextView的LongClick事件。

    然而结果是点击ClickableSpan响应正常;但是长按ClickableSpan时问题出现了:TextView的长按事件响应了,ClickableSpan点击事件也响应了!

    研究了一下代码,解决方法如下:

    继承LinkMovementMethod,然后重写里面的onTouchEvent方法,在里面判断,如果当前是长按的状态,则不执行ClickableSpan的onClick事件:

    package com.kanchufang.privatedoctor.util.spannableparser;
    
    import android.text.Layout;
    import android.text.Selection;
    import android.text.Spannable;
    import android.text.method.LinkMovementMethod;
    import android.text.style.ClickableSpan;
    import android.view.MotionEvent;
    import android.widget.TextView;
    
    /**
     * Author: wangjie
     * Email: tiantian.china.2@gmail.com
     * Date: 7/3/14.
     */
    public class LinkMovementClickMethod extends LinkMovementMethod{
    
        private long lastClickTime;
    
        private static final long CLICK_DELAY = 500l;
    
        @Override
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            int action = event.getAction();
    
            if (action == MotionEvent.ACTION_UP ||
                    action == MotionEvent.ACTION_DOWN) {
                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);
    
                ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
    
                if (link.length != 0) {
                    if (action == MotionEvent.ACTION_UP) {
                        if(System.currentTimeMillis() - lastClickTime < CLICK_DELAY){
                            link[0].onClick(widget);
                        }
                    } else if (action == MotionEvent.ACTION_DOWN) {
                        Selection.setSelection(buffer,
                                buffer.getSpanStart(link[0]),
                                buffer.getSpanEnd(link[0]));
                        lastClickTime = System.currentTimeMillis();
                    }
    
                    return true;
                } else {
                    Selection.removeSelection(buffer);
                }
            }
            return super.onTouchEvent(widget, buffer, event);
        }
    
        public static LinkMovementClickMethod getInstance(){
            if(null == sInstance){
                sInstance = new LinkMovementClickMethod();
            }
            return sInstance;
        }
    
        private static LinkMovementClickMethod sInstance;
    
    }

    代码很简单,按住超过500ms,则认定为是长按,则不执行ClickableSpan的onClick

  • 相关阅读:
    [Leetcode][Python][DP]Regular Expression Matching
    [LeetCode][Python]Container With Most Water
    [LeetCode][Python]Regular Expression Matching
    [LeetCode][Python]Palindrome Number
    [LeetCode][Python]Largest Number
    前后端数据交互的几个方法
    AngularJS中服务和自定义服务的常见方式及特点
    uniapp解决图形验证码问题及arraybuffer二进制转base64格式图片
    动态面包屑组件(适合嵌套路由)
    vue + antd-vue + 腾讯云点播 完成视频上传功能
  • 原文地址:https://www.cnblogs.com/tiantianbyconan/p/3823429.html
Copyright © 2011-2022 走看看