代码改变世界

android 自定义TextView支持微博功能后在ListView占用了Item点击的解决办法

2013-04-02 09:36 by Terry_龙, ... 阅读, ... 评论, 收藏, 编辑

使用setMovementMethod才能使TextView里面的元素自动拥有点击功能,支持ClickSpan。但是加上这个方法会造成ListView的每个项无的文本会占用ListView的ItemClick,解决这个办法需要重写一个setMovementMethod方法,详见代码如下:

public class TextViewFixTouchConsume extends TextView {
boolean dontConsumeNonUrlClicks = true;
boolean linkHit;

public TextViewFixTouchConsume(Context context) {
    super(context);
}

public TextViewFixTouchConsume(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public TextViewFixTouchConsume(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    linkHit = false;
    boolean res = super.onTouchEvent(event);

    if (dontConsumeNonUrlClicks)
        return linkHit;
    return res;

}

public void setTextViewHTML(String html)
{
    CharSequence sequence = Html.fromHtml(html);
    SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
    setText(strBuilder);
}

public static class LocalLinkMovementMethod extends LinkMovementMethod{
    static LocalLinkMovementMethod sInstance;


    public static LocalLinkMovementMethod getInstance() {
        if (sInstance == null)
            sInstance = new LocalLinkMovementMethod();

        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) {
            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]));
                }

                if (widget instanceof TextViewFixTouchConsume){
                    ((TextViewFixTouchConsume) widget).linkHit = true;
                }
                return true;
            } else {
                Selection.removeSelection(buffer);
                Touch.onTouchEvent(widget, buffer, event);
                return false;
            }
        }
        return Touch.onTouchEvent(widget, buffer, event);
    }
}
}

以上加红的两个代码必须要重写。随后你就可以这么使用

setMovementMethod(TextViewFixTouchConsume.LocalLinkMovementMethod.getInstance());

这样即给TextView增加点击效果,又不让其占用Item的点击焦点。类似微博的@ 、表情、链接等。

 

最后发个图,给大家参考