2011-10-31 78 views
18

我有一個列表視圖,除了一些其他視圖之外,每行都包含一個TextView。 TextView呈現可能包含鏈接的html內容。Android的ListView沒有收到OnItemClick爲可點擊鏈接的textview

下面的代碼出現在列表適配器中。 m_textview.setMovementMethod(LinkMovementMethod.getInstance()); m_textview.setText(Html.fromHtml(myhtmlcontent));

雖然這會導致listview不再接收點擊事件。我決定在適配器返回的視圖上放置列表onclick代碼。這並不像預期的那樣工作。現在我可以啓動另一個活動,當我點擊行中除textview之外的任何地方。我希望用戶能夠點擊textview的非鏈接部分並啓動另一項活動。

如果我將onclick移動到textview而不是它的父視圖,它可以工作,但現在單擊鏈接會觸發兩個事件 - 一個用於點擊鏈接,另一個用於textview(這不是期望的)。

我注意到,谷歌+和窺視安卓工作在我想要的方式。我不確定如何實現。

回答

1

ListView項目內部的可聚焦視圖將禁用選擇ListView項目的能力。向TextView應用android:focusable="false"將允許OnItemClick再次運行。您可能還需要應用android:focusableInTouchMode="false"以使軌跡球忽略鏈接,因爲在ListView中的可聚焦元素上單擊軌跡球可以同時單擊該鏈接和ListView項目。

21

這實際上是一個BUG。要解決這個問題,你可以添加android:descendantFocusability="blocksDescendants"你的ListView's行佈局xml。對於e.g

<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

好運:)

+0

這可能是太晚了..但我有同樣的問題,發現這個沒有答案帖子。 :) –

0

,可以在列表上附上查看setOnItemClickListener。

0

我有同樣的問題,沒有這些答案爲我工作。最終,我設法通過刪除屬性android:inputType="textMultiLine"來解決問題。

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