Android: ListView no recibe OnItemClick para textview con enlaces que se pueden hacer clic
Tengo un ListView que contiene un TextView en cada fila además de un número de otras vistas. El TextView procesa contenido html que puede contener vínculos.
El código siguiente aparece en el adaptador de lista. M_textview.setMovementMethod (LinkMovementMethod.getInstance ()); M_textview.setText (Html.fromHtml (myhtmlcontent));
Esto hace que el listview ya no reciba eventos de clic. Decidí poner el código del onclick de la lista en la opinión que era vuelta por el adaptador en lugar de otro. Esto no funciona bien como se desee. Ahora puedo iniciar otra actividad cuando haga clic en cualquier parte de la fila, excepto la vista de texto. Quiero que los usuarios puedan hacer clic en la parte no vinculada de la vista de texto y iniciar otra actividad.
Si muevo el onclick a la vista de texto en lugar de su vista principal, funciona, pero ahora un clic en el enlace dispara dos eventos: uno para el clic en el enlace y otro para el texto (que no se desea).
He notado que google + y peep en android trabajo de la manera que quiero. No estoy seguro de cómo se puede lograr.
Esto es realmente un BUG . Para resolver esto puedes añadir android:descendantFocusability="blocksDescendants"
tu android:descendantFocusability="blocksDescendants"
xml de ListView's
. Por ejemplo
<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>
Fuente: esto y este
Buena suerte 🙂
Las vistas orientables dentro de un elemento ListView desactivarán la capacidad de seleccionar elementos ListView. Aplicar android:focusable="false"
a TextView permitirá OnItemClick para trabajar de nuevo. También es posible que necesites aplicar android:focusableInTouchMode="false"
para hacer que la trackball ignore los enlaces porque hacer clic en la trackball sobre un elemento que se puede enfocar en un ListView puede hacer clic en el enlace y en el elemento ListView.
Puede adjuntar en la vista de lista un setOnItemClickListener.
Tuve el mismo problema y ninguna de estas respuestas funcionó para mí. Eventualmente, logré arreglar el problema eliminando el atributo android:inputType="textMultiLine"
.
TextView que sólo responde a los eventos de contacto de enlaces. Basado en 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); } }