Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo puedo utilizar onTouchListeners en cada palabra en un TextView?

Quisiera asignar onTouchListeners a cada palabra en un TextView. (No para vincular a algo en Internet, sino sólo para continuar la lógica del juego dentro de la aplicación). La acción general de mi juego en este punto es ver un TextView, tocar una palabra, si es la palabra de destino que ganas, o bien cargar otro TextView basado en la palabra que tocas y repetir. La forma en que lograr esto ahora es con ClickableSpans y onClicks para cada palabra.

Pero prefiero tener OnTouchListeners para que pueda cambiar el color del fondo de la palabra en touch_down y hacer la lógica del juego en touch_up, para que parezca más sensible. ¿Cómo puedo lograr esto?

final TextView defTV = (TextView) findViewById(R.id.defTV); text = new SpannableString(rv); // rv is the future clickable TextView text ClickableSpan clickableSpan = null; String regex = "\\w+"; Pattern p = Pattern.compile(regex); Matcher matcher = p.matcher(text); while (matcher.find()) { final int begin = matcher.start(); final int end = matcher.end(); clickableSpan = new ClickableSpan() { public void onClick(View arg0) { String lword = (String) text.subSequence(begin, end).toString(); if (lword.equalsIgnoreCase(targetword)) { // WIN } else { // Build new TextView based on lword, start over } } }; text.setSpan(clickableSpan, begin, end, 0); } 

  • Las filas ListView de Android en ScrollView no se muestran completamente - recortadas
  • ScrollView desplazamientos automáticos para seleccionar TextView
  • Scrollview puede alojar sólo un hijo directo
  • One Solution collect form web for “¿Cómo puedo utilizar onTouchListeners en cada palabra en un TextView?”

    Así que copié ClickableSpan.java y hecho TouchableSpan.java:

     import android.text.TextPaint; import android.text.style.CharacterStyle; import android.text.style.UpdateAppearance; import android.view.MotionEvent; import android.view.View; /** * If an object of this type is attached to the text of a TextView * with a movement method of LinkTouchMovementMethod, the affected spans of * text can be selected. If touched, the {@link #onTouch} method will * be called. */ public abstract class TouchableSpan extends CharacterStyle implements UpdateAppearance { /** * Performs the touch action associated with this span. * @return */ public abstract boolean onTouch(View widget, MotionEvent m); /** * Could make the text underlined or change link color. */ @Override public abstract void updateDrawState(TextPaint ds); } 

    Y extendí LinkMovementMethod.java a LinkTouchMovementMethod.java . El método onTouchEvent es el mismo, excepto para una mención de onClick se cambia a onTouch y se añade una nueva línea:

     import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.method.LinkMovementMethod; import android.view.MotionEvent; import android.widget.TextView; public class LinkTouchMovementMethod extends LinkMovementMethod { @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { 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(); Layout layout = widget.getLayout(); int line = layout.getLineForVertical(y); int off = layout.getOffsetForHorizontal(line, x); TouchableSpan[] link = buffer.getSpans(off, off, TouchableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onTouch(widget,event); //////// CHANGED HERE } else if (action == MotionEvent.ACTION_DOWN) { link[0].onTouch(widget,event); //////// ADDED THIS Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); } } 

    Y establecer el MovementMethod adecuadamente en su código:

     TextView tv = (TextView) findViewById(R.id.tv); tv.setMovementMethod(new LinkTouchMovementMethod()); 

    Ahora para mostrar el texto:

     touchableSpan = new TouchableSpan() { public boolean onTouch(View widget, MotionEvent m) { ... } public void updateDrawState(TextPaint ds) { ds.setUnderlineText(false); ds.setAntiAlias(true); } }; String rv = "Text to span"; text = new SpannableString(rv); text.setSpan(touchableSpan, begin, end, 0); tv.setText(text, BufferType.SPANNABLE); 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.