Android - ListView没有收到带有可点击链接的文本视图的OnItemClick

时间:2011-10-31 20:35:06

标签: android listview textview

我有一个ListView,除了许多其他视图外,每行包含一个TextView。 TextView呈现可能包含链接的html内容。

以下代码显示在列表适配器中。             m_textview.setMovementMethod(LinkMovementMethod.getInstance());             m_textview.setText(Html.fromHtml(myhtmlcontent));

这会导致listview不再接收点击事件。我决定将列表onclick代码放在适配器返回的视图上。这根本不是很有效。现在,当我单击除textview之外的行中的任何位置时,我可以启动另一个活动。我希望用户能够单击textview的非链接部分并启动另一个活动。

如果我将onclick移动到textview而不是其父视图,它可以工作,但现在点击该链接会触发两个事件 - 一个用于链接的单击,另一个用于textview(这是不需要的)。 / p>

我注意到google +并以我想要的方式窥视android工作。我不确定如何实现。

5 个答案:

答案 0 :(得分:23)

这实际上是BUG。要解决此问题,您可以在android:descendantFocusability="blocksDescendants"行布局xml中添加ListView's。例如

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >

 <TextView
    android:id="@+id/lblStatusMessage"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:autoLink="web"
    android:focusable="false"
    android:textSize="15sp" />
</LinearLayout>

来源:thisthis

祝你好运:)

答案 1 :(得分:1)

ListView项目中的可聚焦视图将禁用选择ListView项目的功能。将android:focusable="false"应用于TextView将允许OnItemClick再次工作。您可能还需要应用android:focusableInTouchMode="false"来使轨迹球忽略链接,因为单击ListView中可聚焦元素上的轨迹球可以单击链接和ListView项。

答案 2 :(得分:0)

您可以在列表视图中附加setOnItemClickListener。

答案 3 :(得分:0)

我遇到了同样的问题,这些答案都没有对我有用。最后,我设法通过删除属性android:inputType="textMultiLine"来解决问题。

答案 4 :(得分:0)

仅响应链接触摸事件的TextView。基于                        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);
            }
        }