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


¿Es posible agregar un TextView desplazable a un ListView?

Tengo un ListView donde cada fila tiene una altura fija.
Cada fila contiene, junto a algunas imágenes, un TextView.
A veces, el texto que quiero mostrar es demasiado grande y por lo tanto, me gustaría hacerlo desplazable.
Así que he añadido (basado en hacer TextView desplazable en Android ) las siguientes líneas a mi TextView

text.setMaxLines(5); text.setVerticalScrollBarEnabled(true); text.setMovementMethod(ScrollingMovementMethod.getInstance()); 

Esto funciona bien si uso el TextView de forma aislada, pero no cuando pongo el TextView dentro de un ListView:
Tan pronto como hago un desplazamiento vertical, los eventos parecen ser consumidos por el ListView.

¿Alguna sugerencia sobre cómo puedo hacer que esto funcione?

La actividad completa (prueba) se agrega a continuación (no layout.xml)

 public class TestScrollableTextView extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); //add a ListView ListView list = new ListView(this); layout.addView(list); list.setAdapter(new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) { TextView text = new TextView(TestScrollableTextView.this); String s = ""; //add 10 lines of text, all but first are indented for (int i = 0; i < 10; i++) { if(i>0) s+="\t"; s += "position "+position+"; line="+i+"\n"; } text.setText(s); text.setMaxLines(5); text.setVerticalScrollBarEnabled(true); text.setMovementMethod(ScrollingMovementMethod.getInstance()); return text; } @Override public long getItemId(int position) { return 0; } @Override public Object getItem(int position) { return null; } @Override public int getCount() { return 20; } }); setContentView(layout); } } 

4 Solutions collect form web for “¿Es posible agregar un TextView desplazable a un ListView?”

GetLineCount y getLineHieght y compruebe si el Texto es mayor que TextView.

Si utiliza este código, se puede desplazar el listView tocando en cualquier lugar que no sea TextView con (boolean) isLarger = true.

 text.setText(s); text.setMaxLines(100); text.setVerticalScrollBarEnabled(true); text.setMovementMethod(new ScrollingMovementMethod()); OnTouchListener listener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { boolean isLarger; isLarger = ((TextView) v).getLineCount() * ((TextView) v).getLineHeight() > v.getHeight(); if (event.getAction() == MotionEvent.ACTION_MOVE && isLarger) { v.getParent().requestDisallowInterceptTouchEvent(true); } else { v.getParent().requestDisallowInterceptTouchEvent(false); } return false; } }; text.setOnTouchListener(listener); 

Puedo hacer este trabajo creando una subclase de ListView y sobreescribir onTouchEvent como sigue:
– Compruebo primero si el MotionEvent está dentro de un childView
– si es así, llamo al onTouchEvent del niño

Esto parece una funcionalidad básica, por lo que me sorprende que esto no sea manejado por ListView. ¿Me estoy perdiendo de algo?

  @Override public boolean onTouchEvent(MotionEvent event) { //find correct child View theChild = null; boolean handled = false; for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); Rect rect = new Rect(); child.getDrawingRect(rect); offsetDescendantRectToMyCoords(child, rect); if(rect.contains((int)event.getX(), (int)event.getY())) { theChild = child; } } if(theChild!=null) { handled = theChild.onTouchEvent(event); } if(!handled) handled = super.onTouchEvent(event); return handled; } 

Una mejor manera es probablemente crear su propio MyTextView de la siguiente manera y llamar a requestDisallowInterceptTouchEvent. Al hacerlo, indica a la lista que no debe interceptar eventos.

 class MyTextView extends TextView { public MyTextView(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public boolean dispatchTouchEvent(MotionEvent event) { boolean ret; ret = super.dispatchTouchEvent(event); if(ret) { list.requestDisallowInterceptTouchEvent(true); } return ret; } } 

Utilice este Custom para resolver su problema.

 public class ScrollableListView extends ListView { public ScrollableListView(Context context) { super(context); } public ScrollableListView(Context context, AttributeSet attrs) { super(context, attrs); } public ScrollableListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false"); super.onTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: return false; // redirect MotionEvents to ourself case MotionEvent.ACTION_CANCEL: Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false"); super.onTouchEvent(ev); break; case MotionEvent.ACTION_UP: Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false"); return false; default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action); break; } return false; } @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction()); return true; } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.