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>
Suresh
fonte

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
fonte
@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();
ritesh4326
fonte
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.

user3044482
fonte
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);
    }
});
Ignas
fonte