Agregar nuevos elementos a la parte superior de ListView

Estoy escribiendo un cliente de mensajería instantánea y necesito descargar (desde el sistema de archivos o la red) y mostrar nuevos elementos en la parte superior de ListView (es el historial de mensajes; los mensajes más antiguos están en la parte superior, los más nuevos, en la parte inferior). Implementé mi propio Adaptador para ListView pero no puedo agregar nuevos elementos al principio de la lista y volver a dibujarla. (notifyDataSetChanged() no es bueno para mí, porque los índices de mensajes en ListView cambian y Android no puede volver a dibujarlo normalmente).

¿Cómo otras aplicaciones hacen algo similar?

No creo un código especial para él, simplemente estoy creando un nuevo adaptador para mi ListView:

messagesListView.setAdapter(new MessagesListAdapter(this));

Y redefina el método getView() y getCount() en MessagesListAdapter (extiende ArrayAdapter ahora).

Mi XML para ListView es

<ListView
  android:id="@+id/dialog_messages_list"
  android:layout_height="fill_parent"
  android:layout_width="fill_parent"
  android:layout_marginTop="@dimen/title_height">
</ListView>

Y mi XML para un elemento (un mensaje) es

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal" >

  <TextView
      android:id="@+id/dialogMessageText"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text=""
      android:background="@drawable/dialog_message_in"
      />

  <TextView
    android:id="@+id/dialogMessageDatetime"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text=""/>

</LinearLayout>

¿Puede ser que necesites otro código?

EDITAR: lo intenté

    messagesListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList));
    (new Thread() {
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            arrayList.add(0, "qwer");
        }
    }).start();

Pero tampoco parece bueno. traté de llamar ((ArrayAdapter<String>)messagesListView.getAdapter()).notifyDataSetChanged(); en el hilo, pero hace una excepción.

preguntado el 01 de julio de 12 a las 19:07

Publique el código relevante y cualquier error que reciba. Hay muchas maneras de hacer esto. Me centraría en cómo se ordena el historial, no en ListView o Adapter. -

Lo siento, @Sam, llevo mucho tiempo versado en los comentarios de StackOverflow. Lo siento. La historia es simplemente ArrayList por ejemplo, pero en algún momento quiero agregar nuevos elementos al comienzo de la misma. Puede ser Deque, si es simple. ¿Entiendo bien tu pregunta? -

Ok, ¿dónde creas el ArrayList? para llenar el ListView? -

Crea en otro hilo, y ListView accede a él mediante el campo estático de otra clase. -

¿Podrías publicar dónde creas y llenas el ArrayList? ? -

2 Respuestas

Sugiero invertir el orden de la Lista para mostrar primero el resultado más reciente.

Ejecuta este ejemplo:

public class Example extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String[] array = {"oldest", "older", "old", "new", "newer"};
        List<String> list = new ArrayList<String>();
        Collections.addAll(list, array);
        Collections.reverse(list);

        // When you want to add new Strings, put them at the beginning of list
        list.add(0, "newest");

        ListView listView = (ListView) findViewById(R.id.list);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
        listView.setAdapter(adapter);
    }
}

No tiene que anular nada en ArrayAdapter o ListView de esta manera.

Respondido 01 Jul 12, 21:07

puede agregar mediante programación algunas vistas en la clase asociada con su vista de lista. Por ejemplo:

Para agregar cosas a un diseño y crear nuevos elementos:

TextView tv = new TextView(getApplicationContext());
EditText edit = new EditText(getApplicationContext());
relative.addView(tv);
relative.addView(edit);

Esto es para manipular un elemento existente en el diseño xml:

final TextView tv = (TextView) v.findViewById(R.id.listItem);
    tv.setText("This an item I am changing");

Si observa algunas de las preguntas relacionadas, le darán más información al respecto. Pero también puede consultar en línea las vistas de lista personalizadas y los adaptadores de otras personas. Este es muy bonito: http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

Respondido 01 Jul 12, 19:07

Pero según la documentación (desarrollador.android.com/reference/android/widget/ListView.html) No puedo agregar vistas a ListView. Y realmente no puedo, tengo la excepción. - andres gein

@jeremy-d, obtuve "java.lang.UnsupportedOperationException: addView(View) no es compatible con AdapterView" - andres gein

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.