Mantener el último elemento visible de un ListView cuando el tamaño del ListView cambia

Lo que quiero es simple, bueno por lo menos pensé que sería simple. Sólo quiero una ventana donde un EditText está en la parte inferior de la pantalla, y el resto del espacio está lleno de ListView. Por desgracia, no funcionaba como esperaba. Lo que quiero es la siguiente imagen. ¿Hay alguna manera fácil de hacer esto en el XML, o debería escribir algún código especial para esto? Lo que quiero

Mi código fuente Android problemático.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/demolist" android:layout_width="match_parent" android:layout_height="fill_parent" android:layout_weight="1" > </ListView> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0"> </EditText> </LinearLayout > 

12 Solutions collect form web for “Mantener el último elemento visible de un ListView cuando el tamaño del ListView cambia”

Lo que quieras

Último elemento visible sin teclado

Último elemento visible sin teclado

Último artículo visible con teclado

Último artículo visible con teclado

Último artículo visible Con una entrada más grande

Último artículo visible Con una entrada más grande

Aquí es cómo lo hice.

Resumen

  • Establecer android: stackFromBottom = "true" and android: transcriptMode = "alwaysScroll" en la vista de lista
  • Establecer android: windowSoftInputMode = "adjustPan" en la actividad
  • Llame a adapter.notifyDataSetChanged (); Cuando agregue nuevos chats para que la vista de lista siempre se desplace hasta la última posición
  • Establecer android: inputType = "textMultiLine" & android: maxLines = "4" en EditText para el cuadro de texto en crecimiento

Detalles

Actividad

 <activity android:name="MainActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan"></activity> 

Vista de la charla

 <RelativeLayout android:id="@+id/chat_header" android:layout_width="fill_parent" android:layout_height="40dp" android:padding="3dp" > <Button android:id="@+id/btnBackChat" android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentLeft="true" android:background="@drawable/back_button" /> <TextView android:id="@+id/txt_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/btnBackChat" android:layout_centerHorizontal="true" android:textColor="@android:color/white" android:textSize="18sp" /> <ImageView android:id="@+id/imgViewProfileChat" android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentRight="true" /> </RelativeLayout> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/form" android:layout_below="@+id/chat_header" android:stackFromBottom="true" android:transcriptMode="alwaysScroll"/> <RelativeLayout android:id="@+id/form" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:orientation="vertical" > <ImageButton android:id="@+id/btnAttach" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:contentDescription="@string/attach" android:src="@drawable/attach_icon" /> <EditText android:id="@+id/txtChat" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/btnSend" android:layout_toRightOf="@+id/btnAttach" android:inputType="textMultiLine" android:maxLines="4" /> <Button android:id="@+id/btnSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="@string/send" /> </RelativeLayout> 

Creo que puede que desee utilizar AdapterView.getLastVisiblePosition () antes de mostrar el teclado.

Dos soluciones aquí:

  • En EditText clic
  • Gracias a un OnScrollListener (y su función onScroll) escuchando su ListView

A continuación, utilice AdapterView.setSelection para saltar a este elemento (o índice – 2 o índice – 3) después del enfoque de EditText.

Puedes usar android:windowSoftInputMode="adjustPan" en tu AndroidManifest.xml como se muestra a continuación

  <activity android:name="com.example.SimpleListView" android:label="@string/app_name" android:windowSoftInputMode="adjustPan" > 

Esto debería producir la salida que desea. Documentación oficial de Android .

Opcionalmente, puede especificar el modo de transcripción (si está trabajando en alguna función de chat) para su vista de lista si desea desplazarse automáticamente al final de listview. Usted puede comprobar el android:transcriptMode="normal" también y ver si encaja.

Una respuesta relacionada. Oficial android doc .

 <ListView android:id="@+id/comments" android:layout_width="match_parent" android:layout_height="match_parent" android:transcriptMode="alwaysScroll"> 

Esto debería resolver la mayoría de sus problemas, tal vez excepto el último (en la imagen) que no he probado.

Simplemente anule el método de ListView # onSizeChanged (int, int, ht, int oldw, int oldh) como a continuación: PS: La altura de tu ListView no puede ser 0 en cualquier momento, si puede 0, no funciona.

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (getChildCount() == 0) { return; } final int lastVisiblePosition = getLastVisiblePosition(); int firstVisiblePosition = getFirstVisiblePosition(); View last = getChildAt(lastVisiblePosition - firstVisiblePosition); int top = last.getTop(); final int newTop = top + (h - oldh); Log.d(getClass().getSimpleName(), "onSizeChanged(" + w + ", " + h + ", " + oldw + ", " + oldh + ")"); if (mFocusSelector == null) { mFocusSelector = new FocusSelector(); } post(mFocusSelector.setup(lastVisiblePosition, newTop)); super.onSizeChanged(w, h, oldw, oldh); } private class FocusSelector implements Runnable { private int mPosition; private int mPositionTop; public FocusSelector setup(int position, int top) { mPosition = position; mPositionTop = top; return this; } public void run() { setSelectionFromTop(mPosition, mPositionTop); } } 

En realidad, obtuve el mismo comportamiento que se necesita añadiendo a la declaración de Activity en el manifiesto android:windowSoftInputMode="adjustResize" y la declaración ListView android:transcriptMode="normal" . Tanto para el teclado como para los cambios de orientación.

Necesito esta funcionalidad también. Aquí está mi intento, pero no funciona bien – El desplazamiento es un poco errático (no siempre termina donde debe) y interfiere con la preservación de la posición de desplazamiento al girar la pantalla.

 @Override public void onResume() { super.onResume(); getListView().addOnLayoutChangeListener(stickyLastItemHandler); } @Override public void onPause() { super.onPause(); getListView().removeOnLayoutChangeListener(stickyLastItemHandler); } View.OnLayoutChangeListener stickyLastItemHandler = new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { final int heightChange = (bottom - top) - (oldBottom - oldTop); if (heightChange != 0) { ((AbsListView)v).smoothScrollBy(-heightChange, 1000); } } }; 

Puede hacerlo a través de xml:

 <ListView android:stackFromBottom="true" android:layout_height=0dp android:layout_weight=1 /> 

Apilado desde la parte inferior mantendrá ListView desplazado por defecto por defecto, la fijación de peso de ListView llenará todo el espacio posible dentro vertical LinearLayout padre.

He creado un motor de diseño para Android que le permite escuchar los cambios de estado ocultos y visibles del teclado (entre muchas otras características principales). Esta biblioteca está disponible en http://phil-brown.github.io/AbLE/ .

Simplemente agregue el jar a su directorio libs (cree esta carpeta si no existe), y en lugar de heredar de una Activity , heredar de AbLEActivity . A continuación, onKeyboardShown los métodos onKeyboardShown y onKeyboardShown y, en estos, puede animar su vista de contenido hacia arriba o hacia abajo según sea necesario:

 @Override public void onKeyboardShown() { //animate up } @Override public void onKeyboardHidden() { //animate down } 

Solo echa un vistazo a esto: espero que esto te ayude ….

Suponiendo que sepa cuándo los datos de la lista han cambiado, puede decirle manualmente a la lista que se desplace a la parte inferior estableciendo la selección de la lista en la última fila. Algo como esto:

 private void scrollMyListViewToBottom() { myListView.post(new Runnable() { @Override public void run() { // Select the last row so it will scroll into view... myListView.setSelection(myListAdapter.getCount() - 1) ; } }); } 

O también puedes probar esto .. funciona para mí:

 ChatAdapter adapter = new ChatAdapter(this); ListView lview = (ListView) findViewById(R.id.chatList); lview .setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); lview .setAdapter(adapter); adapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { super.onChanged(); lv.setSelection(adapter.getCount() - 1); } }); 
 Follow these steps -------------------- 1. Update your activity in AndroidManifest.xml file like below <activity android:name=".MyListActivity" android:windowSoftInputMode="adjustResize" /> 2. Set your list view with like below. mListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); mListView.setStackFromBottom(true); 

Espero que solucione su problema.

En su ListAdapter, podría hacer algo como esto:

  public View getView(int position, View convertView, ViewGroup parent) { //buttonMore if( position >= super.getCount() ) return textField ; .... 

De esta manera, siempre obtendrá su último elemento en la lista como su campo de texto.

Usted necesita fijar la posición de la selección … Pero – de una manera extraña, no entiendo realmente porqué – usted necesita hacerlo con el poste ()

 public void ScrollToLast() { yourList.clearFocus(); yourList.post(new Runnable() { @Override public void run() { yourList.setSelection(items.size() - 1); } }); } 

Así que puede agregar un TextWatcher para su editText y puede llamar a este método allí … Así que su lista se desplaza a la parte inferior.

  • ¿Dónde puedo encontrar el archivo xml de configuración predeterminado de AlertDialog?
  • Vista personalizada para ActionBar.Tab no se muestra correctamente
  • El contenido vertical se alinea en Android EditText
  • ¿Cómo añadir una imagen gif como un icono de carga de Android?
  • EditText oculto por el teclado cuando android: gravity = "center" - Android
  • EditText añadido programaticamente difiere de la versión XML
  • Diferencia entre setContentView y LayoutInflater
  • Android: Pregunta sobre tamaño / resolución de aplicaciones independientes?
  • Los botones deben ser tan anchos como los
  • Agregar sombra debajo TabBar - Diseño de material
  • Cambiar iconos del menú ActionBar según el estilo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.