Estoy usando un OnScrollListener agregar dinámicamente los elementos de un ListView cuando el usuario se desplaza a la parte inferior. Después de agregar los datos para el adaptador y llame a notifyDataSetChanged sin embargo, el ListView sube a la parte superior. Idealmente, me gustaría conservar la posición en el ListView. Alguna idea sobre cómo debo hacer esto?

  • Hola por favor puede compartir la forma de u tiene conservan y utilizan estado actual de la vista de lista en OnScrollListener… estoy haciendo lo mismo, pero yo actualización de la lista de Async tarea…….. no funciona de alguna forma
  • Solución Simple: stackoverflow.com/a/28149739/1468093
  • el uso de @KamranAhmed ‘s respuesta. solución sencilla y elegante. de hecho, la correcta aun
InformationsquelleAutor SeanPONeil | 2011-11-26

7 Comentarios

  1. 97

    Podría ser esto lo que quieres?

    //save index and top position
    int index = mList.getFirstVisiblePosition();
    View v = mList.getChildAt(0);
    int top = (v == null) ? 0 : v.getTop();
    
    //notify dataset changed or re-assign adapter here
    
    //restore the position of listview
    mList.setSelectionFromTop(index, top);

    EDITAR 28/09/2017:

    La API ha cambiado bastante desde 2015. Es similar, pero ahora sería:

    //save index and top position
    int index = mList.FirstVisiblePosition; //This changed
    View v = mList.getChildAt(0);
    int top = (v == null) ? 0 : v.Top; //this changed
    
    //notify dataset changed or re-assign adapter here
    
    //restore the position of listview
    mList.setSelectionFromTop(index, top);
    • Gracias. Si desea agregar elementos a la parte superior de la lista sin ver la actualización a ocurrir, usted tendrá que agregar el número de elementos que se agregan al índice de tipo int. int índice = mList.getFirstVisiblePosition() + NUMBER_OF_ADDED_ITEMS;
    • Si setSelection no funciona inmediatamente después de llamar a notifyDataSetChanged, he aquí una solución: getListView().postDelayed(new Runnable() { @Override public void run() { getListView().setSelection(8); } }, 500); Android es un bicho supuestamente asignado, por lo que este debe ser fija en algún punto: code.google.com/p/android/issues/detail?id=6741
    • Funciona a la perfección. También, en caso que ayuda a otra persona, este no estaba trabajando, en primer lugar para mí. Hasta que me di cuenta de que en algunos de los anteriores infinita sabiduría de la mina, había añadido lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL). No hagas eso… va con fuerza desplácese hasta la parte inferior de su listview hasta que usted ha tirado la mayor parte de su cabello. ja.
    • He utilizado getScrollX() y setScrollX() en lugar de getFirstVisiblePosition() y setSelectionFromTop(), como que todavía causado algunos pequeños saltos al agregar contenido.
    • He utilizado el (sin retardo) método post para que funcione, por desgracia, todavía parpadea durante la actualización.
    • ¿qué es mList? Es un objeto de listView clase? Y ¿dónde pongo este código, justo después de listViewObj.setAdapter(adapter)?
    • este es completa copiar-pegar desde aquí, stackoverflow.com/questions/3014089/…
    • Gracias! Esto era lo que yo necesitaba!
    • Con el fin de evitar el parpadeo, he seguido las instrucciones de stackoverflow.com/q/19320214/2343626 . Lo que tienes que hacer es registrarse un OnPreDrawListener el control listview y, a continuación, puede omitir el sorteo de la solicitud hecha por el adaptador y permitir sólo el sorteo de la solicitud que se hizo cuando usted llama setSelectionFromTop.
    • setSelectionFromTop llamar requiere un mínimo nivel de API 21. ¿Qué acerca de la ejecución en pre 21 de dispositivos ?

  2. 6

    La situación:

    Cuando se establece un adaptador a su listview, actualiza su estado. Así, normalmente se desplaza automáticamente.

    La solución:

    Asignar un adaptador para listview si no tiene ninguna, sólo actualizar el conjunto de datos de la asignación de adaptador, no volver a configurarlo a tu listview.

    Un detallado tutorial se explica en el siguiente enlace;

    Android ListView: Mantener su posición de desplazamiento al actualizar

    Buena Suerte!

    • Esto funciona de una manera como la posición de desplazamiento no se mueve si puedo agregar un elemento adicional, pero la lista dentro de la vista salta abajo para dar cabida al nuevo elemento.
    • Esta es la solución correcta, no «hacking» para conseguir algo así de simple.
  3. 0

    He implementado la postDelayed y yo estaba parpadeando tras una actualización. Puedo buscar un poco más y descubrí que yo estaba haciendo las cosas mal. Básicamente, yo no debería crear un nuevo adaptador, cada vez que quería cambiar los datos. Terminé haciendo de esta manera y funciona:

    //goes into your adapter
    public void repopulateData(String[] objects) {
        this.objects = null;
        this.objects = objects;
        notifyDataSetChanged();
    }
    
    //goes into your activity or list
    if (adapter == null) {
        adapter = new Adapter();
    } else {
        adapter.repopulateData((String[])data);
    }

    Espero que esto ayude.

  4. 0

    Estoy usando

    listView.getFirstVisiblePosition

    para mantener la última posición visible.

  5. 0

    Probar este

          boolean first=true; 
          protected void onPostExecute(Void result) 
          {
    
          if (first == true) {
          listview.setAdapter(customAdapter);
          first=false;
          }
          else
          customAdapter.notifyDataSetChanged();
          }
  6. 0

    Aquí está el código:

    //Save the ListView state (= includes scroll position) as a Parceble
    Parcelable state = listView.onSaveInstanceState();
    
    //e.g. set new items
    listView.setAdapter(adapter);
    
    //Restore previous state (including selected item index and scroll position)
    listView.onRestoreInstanceState(state);  

Dejar respuesta

Please enter your comment!
Please enter your name here