Atualizando a visualização da lista quando os dados do adaptador mudam


104

Quando os dados associados ao adaptador de array são alterados, invalidar o listview é suficiente para mostrar os valores atualizados? O trecho de código a seguir não está funcionando, entendi mal alguma coisa aqui.?

public class ZeroItemListActivity extends Activity {
    private ArrayList<String> listItems=new ArrayList<String>();
    private ListView mMyListView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMyListView=(ListView) findViewById(R.id.MyListView);
        mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
    }
    public void addItem(View v){
        listItems.add("list Item");
        mMyListView.invalidate();
    }
}

Layout usado:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="@string/hello" />
    <ListView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/MyListView"></ListView>
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/AddItemsButton"
        android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>

Respostas:


172

substituto:

mMyListView.invalidate();

para:

((BaseAdapter) mMyListView.getAdapter()).notifyDataSetChanged(); 

Se isso não funcionar, consulte este tópico: Atualização da visualização de lista do Android


@blindstuff se eu tiver que atualizar um único item do listview então o que eu tenho que fazer
Desenvolvedor

Se BaseAdapter não existir, notificarDataSetChanged () não aparecerá, então você precisa mudar BaseAdapterparaYourCustomAdapter
Junior Mayhé

12

Mude esta linha:

mMyListView.setAdapter(new ArrayAdapter<String>(this, 
                           android.R.layout.simple_list_item_1, 
                           listItems));

para:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                   android.R.layout.simple_list_item_1, 
                                   listItems)
mMyListView.setAdapter(adapter);

e depois de atualizar o valor de um item da lista, chame:

adapter.notifyDataSetChanged();

3

invalidate(); chama a exibição de lista para se invalidar (ou seja, cor de fundo)
invalidateViews(); chama todos os seus filhos para serem invalidados. permitindo que você atualize as visualizações dos filhos

Presumo que seja algum tipo de coisa de eficiência evitando que todos os itens tenham que ser constantemente redesenhados se não for necessário.


2

Eu encontrei uma solução que é mais eficiente do que a resposta aceita atualmente, porque a resposta atual força todos os elementos da lista a serem atualizados. Minha solução atualizará apenas um elemento (que foi tocado) chamando os adaptadores getView e reciclando a visualização atual, o que adiciona ainda mais eficiência.

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      // Edit object data that is represented in Viewat at list's "position"
      view = mAdapter.getView(position, view, parent);
    }
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.