Android - ListView doesn't receive OnItemClick for textview with clickable links

前端 未结 5 2153
野趣味
野趣味 2021-02-02 12:55

I have a ListView that contains a TextView in each row besides a number of other views. The TextView renders html content which may contain links.

The below code appear

5条回答
  •  天命终不由人
    2021-02-02 13:06

    TextView that only responds to touch events of links. Based on https://stackoverflow.com/a/7327332/1768722

            public class AutoLinkTextView extends TextView {
    
                public AutoLinkTextView(Context context, AttributeSet attrs, int defStyle) {
                    super(context, attrs, defStyle);
                    init();
                }
    
                public AutoLinkTextView(Context context, AttributeSet attrs) {
                    super(context, attrs);
                    init();
                }
    
                public AutoLinkTextView(Context context) {
                    super(context);
                    init();
                }
    
                private void init() {
                    this.setAutoLinkMask(Linkify.ALL);
                }
    
                /**
                 * @Linkify applies to a movementMethod to the textView @LinkMovementMethod.
                 *          That movement method thought it implements a scrolling
                 *          vertically method it overrides any other scrolling method the
                 *          parent has.
                 * 
                 *          Although touchEvent can be dispached to the parent, the specific
                 *          parent ScrollView needed the whole sequence ACTION_DOWN ,
                 *          ACTION_MOVE, ACTION_UP to perform (sweep detection). So the
                 *          solution to this problem is after applying @Linkify we need to
                 *          remove the textView's scrolling method and handle the @LinkMovementMethod
                 *          link detection action in onTouchEvent of the textView.
                 */
                @Override
                public boolean onTouchEvent(MotionEvent event) {
                    final TextView widget = (TextView) this;
                    final Object text = widget.getText();
                    if (text instanceof Spannable) {
                        final Spannable buffer = (Spannable) text;
                        final 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();
    
                            final Layout layout = widget.getLayout();
                            final int line = layout.getLineForVertical(y);
                            final int off = layout.getOffsetForHorizontal(line, x);
    
                            final 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;
                            }
                        }
    
                    }
                    return false;
                }
    
                @Override
                public void setText(CharSequence text, BufferType type) {
                    super.setText(text, type);
                    this.setMovementMethod(null);
                }
            }
    

提交回复
热议问题