TextView的内部链接支持长按

先创建一个支持处理长按事件的span

public class LongClickableSpan extends ClickableSpan View.OnClickListener l;{
    View.OnClickListener l;
    OnLongClickListener mOnLongClickListener = null;

    public LongClickableSpan(String text, OnClickListener l, OnLongClickListener ll, Context mContext) {
        super(text, l, mContext);
        mOnLongClickListener = ll;
    }

    @Override
    public void onClick(View v) {
        if (l != null) {
            l.onClick(v);
        }
    }

    public void onLongClick(View view) {
        if (mOnLongClickListener != null) {
            mOnLongClickListener.onLongClick(view);
        }
    }
}

再重写一个LinkMovementMethod

public class LongClickLinkMovementMethod extends LinkMovementMethod {
    private static LongClickLinkMovementMethod sInstance;
    private static int LONG_CLICK_TIME = 1000;
    private Long lastClickTime = 0l;
    private int lastX = 0;
    private int lastY = 0;
    // 本次点击是否已相应长按事件
    private boolean LongClickCalled = false;

    public static LinkMovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new LongClickLinkMovementMethod();
        }
        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            lastX = x;
            lastY = y;
            int deltaX = Math.abs(x - lastX);
            int deltaY = Math.abs(y - lastY);

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

            LongClickableSpan[] link = buffer.getSpans(off, off, LongClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    // 相应长按事件后不再相应点击事件
                    if (!LongClickCalled) {
                        link[0].onClick(widget);
                    }
                    LongClickCalled = false;
                } else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
                    lastClickTime = System.currentTimeMillis();
                } else if (action == MotionEvent.ACTION_MOVE) {
                    long delta = System.currentTimeMillis() - lastClickTime;
                    if (delta > LONG_CLICK_TIME && !LongClickCalled && deltaX < 10 && deltaY < 10) {
                        LongClickCalled = true;
                        link[0].onLongClick(widget);
                    }
                }
                return true;
            }
        } else if (action == MotionEvent.ACTION_CANCEL) {
            LongClickCalled = false;
        }

        return super.onTouchEvent(widget, buffer, event);
    }

}

使用代码:

TextView textView;
textView.setText(text);//此处text内加入LongClickableSpan的配置
textView.setMovementMethod(LongClickLinkMovementMethod.getInstance());


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值