textview文本片段点击事件与textview点击事件冲突执行两次(最终解决办法)

来源:互联网 发布:ios微信无法连接网络 编辑:程序博客网 时间:2024/05/22 15:10
开发项目中遇到 需要在一个textview中能够点击@好友跳转 用的是下面的方法:
SpannableString nameSpan = new SpannableString(name);    nameSpan.setSpan(new ClickableSpan() {        @Override        public void onClick(View widget) {            // TODO Auto-generated method stub        }    }, 0, nameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

但是写好后发现 再点击“@好友“之后会同时执行上面的ClickableSpan的onClick方法和textview的监听器onClick方法。

百思不得其解,在网上搜了一下午都找不到满意的答案,看来都是你抄我的我抄你的,抄来抄去,看着都生气;

最后还是国外某个网站上搜到的,虽然英文不咋好,还是跌跌撞撞搜到了答案;o(╯□╰)o (不说废话了,直接上答案):

import android.text.Layout;import android.text.NoCopySpan;import android.text.Selection;import android.text.Spannable;import android.text.method.MovementMethod;import android.text.method.ScrollingMovementMethod;import android.text.style.ClickableSpan;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.widget.TextView;public class        CustomLinkMovementMethod        extends ScrollingMovementMethod{    private static final int CLICK = 1;    private static final int UP = 2;    private static final int DOWN = 3;public abstract interface TextClickedListener {    public abstract void onTextClicked();}TextClickedListener listener = null;public void setOnTextClickListener(TextClickedListener listen){    listener = listen;}@Overridepublic boolean onKeyDown(TextView widget, Spannable buffer,                         int keyCode, KeyEvent event) {    switch (keyCode) {        case KeyEvent.KEYCODE_DPAD_CENTER:        case KeyEvent.KEYCODE_ENTER:            if (event.getRepeatCount() == 0) {                if (action(CLICK, widget, buffer)) {                    return true;                }            }    }    return super.onKeyDown(widget, buffer, keyCode, event);}@Overrideprotected boolean up(TextView widget, Spannable buffer) {    if (action(UP, widget, buffer)) {        return true;    }    return super.up(widget, buffer);}@Overrideprotected boolean down(TextView widget, Spannable buffer) {    if (action(DOWN, widget, buffer)) {        return true;    }    return super.down(widget, buffer);}@Overrideprotected boolean left(TextView widget, Spannable buffer) {    if (action(UP, widget, buffer)) {        return true;    }    return super.left(widget, buffer);}@Overrideprotected boolean right(TextView widget, Spannable buffer) {    if (action(DOWN, widget, buffer)) {        return true;    }    return super.right(widget, buffer);}private boolean action(int what, TextView widget, Spannable buffer) {    boolean handled = false;    Layout layout = widget.getLayout();    int padding = widget.getTotalPaddingTop() +            widget.getTotalPaddingBottom();    int areatop = widget.getScrollY();    int areabot = areatop + widget.getHeight() - padding;    int linetop = layout.getLineForVertical(areatop);    int linebot = layout.getLineForVertical(areabot);    int first = layout.getLineStart(linetop);    int last = layout.getLineEnd(linebot);    ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);    int a = Selection.getSelectionStart(buffer);    int b = Selection.getSelectionEnd(buffer);    int selStart = Math.min(a, b);    int selEnd = Math.max(a, b);    if (selStart < 0) {        if (buffer.getSpanStart(FROM_BELOW) >= 0) {            selStart = selEnd = buffer.length();        }    }    if (selStart > last)        selStart = selEnd = Integer.MAX_VALUE;    if (selEnd < first)        selStart = selEnd = -1;    switch (what) {        case CLICK:            if (selStart == selEnd) {                return false;            }            ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);            if (link.length != 1)                return false;            link[0].onClick(widget);            break;        case UP:            int beststart, bestend;            beststart = -1;            bestend = -1;            for (int i = 0; i < candidates.length; i++) {                int end = buffer.getSpanEnd(candidates[i]);                if (end < selEnd || selStart == selEnd) {                    if (end > bestend) {                        beststart = buffer.getSpanStart(candidates[i]);                        bestend = end;                    }                }            }            if (beststart >= 0) {                Selection.setSelection(buffer, bestend, beststart);                return true;            }            break;        case DOWN:            beststart = Integer.MAX_VALUE;            bestend = Integer.MAX_VALUE;            for (int i = 0; i < candidates.length; i++) {                int start = buffer.getSpanStart(candidates[i]);                if (start > selStart || selStart == selEnd) {                    if (start < beststart) {                        beststart = start;                        bestend = buffer.getSpanEnd(candidates[i]);                    }                }            }            if (bestend < Integer.MAX_VALUE) {                Selection.setSelection(buffer, beststart, bestend);                return true;            }            break;    }    return false;}public boolean onKeyUp(TextView widget, Spannable buffer,                       int keyCode, KeyEvent event) {    return false;}@Overridepublic 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) {                link[0].onClick(widget);            } else if (action == MotionEvent.ACTION_DOWN) {                Selection.setSelection(buffer,                        buffer.getSpanStart(link[0]),                        buffer.getSpanEnd(link[0]));            }            return true;        } else {            Selection.removeSelection(buffer);            if (action == MotionEvent.ACTION_UP) {                if(listener != null)                    listener.onTextClicked();            }        }    }    return super.onTouchEvent(widget, buffer, event);}public void initialize(TextView widget, Spannable text) {    Selection.removeSelection(text);    text.removeSpan(FROM_BELOW);}public void onTakeFocus(TextView view, Spannable text, int dir) {    Selection.removeSelection(text);    if ((dir & View.FOCUS_BACKWARD) != 0) {        text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);    } else {        text.removeSpan(FROM_BELOW);    }}public static MovementMethod getInstance() {    if (sInstance == null)        sInstance = new CustomLinkMovementMethod();    return sInstance;}private static CustomLinkMovementMethod sInstance;private static Object FROM_BELOW = new NoCopySpan.Concrete();}在你的代码上加上:
CustomLinkMovementMethod link = (CustomLinkMovementMethod)CustomLinkMovementMethod.getInstance();//textview默认的点击事件可以写在这里,也可以另写(写在这里貌似会有点混乱)link.setOnTextClickListener(new CustomLinkMovementMethod.TextClickedListener() {            @Override            public void onTextClicked() {                Toast.makeText(UserProfileActivity.this, "text Pressed", Toast.LENGTH_LONG).show();            }        });        YOUR_TEXTVIEW.setMovementMethod(link);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

只需要上面这一个就可以了,下面两个也不用加了:

YOUR_TEXTVIEW.setMovementMethod(ScrollingMovementMethod.getInstance());//滑动YOUR_TEXTVIEW.setMovementMethod(LinkMovementMethod.getInstance());//开始响应点击事件
阅读全文
0 0