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

Posted

技术标签:

【中文标题】Android - ListView 没有收到带有可点击链接的文本视图的 OnItemClick【英文标题】:Android - ListView doesn't receive OnItemClick for textview with clickable links 【发布时间】:2011-12-19 01:16:34 【问题描述】:

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

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

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

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

我注意到 google+ 和 peep on android 以我想要的方式工作。我不确定如何实现。

【问题讨论】:

【参考方案1】:

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

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

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

来源:this 和 this

祝你好运:)

【讨论】:

可能为时已晚.. 但我遇到了同样的问题,发现了这个未答复的帖子。 :) 我无法通过文本视图自动链接在我的项目父项上长按监听器来做到这一点【参考方案2】:

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

【讨论】:

【参考方案3】:

您可以在列表视图上附加一个 setOnItemClickListener。

【讨论】:

【参考方案4】:

我遇到了同样的问题,但这些答案都不适合我。最终,我设法通过删除属性android:inputType="textMultiLine" 解决了这个问题。

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于Android - ListView 没有收到带有可点击链接的文本视图的 OnItemClick的主要内容,如果未能解决你的问题,请参考以下文章

带有集合(ListView)的Android小部件不显示项目

带有 ListView 的 Android 可点击小部件在 ListItems 上不可点击

在 Android 中以编程方式创建带有自定义列表项的 ListView - 没有 xml 列表项布局

带有 Intent 和自定义 Listview 的 Android

Android ListView 滚动到底部

listview 没有在带有 viewpager 选项卡的片段中刷新