Quando repovoo meu ListView
, chamo um método específico do meu Adapter
.
Problema :
Quando ligo , updateReceiptsList
meus Adapter
dados são atualizados, mas meus ListView
não refletem a alteração.
Pergunta :
Por que meu ListView
show não mostra os novos dados quando ligo notifyDataSetChanged
?
Adaptador :
public class ReceiptListAdapter extends BaseAdapter {
public List<Receipt> receiptlist;
private Context context;
private LayoutInflater inflater;
private DateHelpers dateH;
public ReceiptListAdapter(Activity activity, Context mcontext, List<Receipt> rl) {
context = mcontext;
receiptlist = rl;
Collections.reverse(receiptlist);
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
dateH = new DateHelpers();
}
@Override
public int getCount() {
try {
int size = receiptlist.size();
return size;
} catch(NullPointerException ex) {
return 0;
}
}
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist = newlist;
this.notifyDataSetChanged();
}
@Override
public Receipt getItem(int i) {
return receiptlist.get(i);
}
@Override
public long getItemId(int i) {
return receiptlist.get(i).getReceiptId() ;
}
private String getPuntenString(Receipt r) {
if(r.getPoints().equals("1")) {
return "1 punt";
}
return r.getPoints()+" punten";
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
final Receipt receipt = receiptlist.get(position);
ReceiptViewHolder receiptviewholder;
Typeface tf_hn = Typeface.createFromAsset(context.getAssets(), "helveticaneue.ttf");
Typeface tf_hn_bold = Typeface.createFromAsset(context.getAssets(), "helveticaneuebd.ttf");
if (vi == null) { //convertview==null
receiptviewholder = new ReceiptViewHolder();
vi = inflater.inflate(R.layout.view_listitem_receipt, null);
vi.setOnClickListener(null);
vi.setOnLongClickListener(null);
vi.setLongClickable(false);
receiptviewholder.shop = (TextView) vi.findViewById(R.id.tv_listitemreceipt_shop);
receiptviewholder.date = (TextView) vi.findViewById(R.id.tv_listitemreceipt_date);
receiptviewholder.price = (TextView) vi.findViewById(R.id.tv_listitemreceipt_price);
receiptviewholder.points = (TextView) vi.findViewById(R.id.tv_listitemreceipt_points);
receiptviewholder.shop.setTypeface(tf_hn_bold);
receiptviewholder.price.setTypeface(tf_hn_bold);
vi.setTag(receiptviewholder);
}else{//convertview is not null
receiptviewholder = (ReceiptViewHolder)vi.getTag();
}
receiptviewholder.shop.setText(receipt.getShop());
receiptviewholder.date.setText(dateH.timestampToDateString(Long.parseLong(receipt.getPurchaseDate())));
receiptviewholder.price.setText("€ "+receipt.getPrice());
receiptviewholder.points.setText(getPuntenString(receipt));
vi.setClickable(false);
return vi;
}
public static class ReceiptViewHolder {
public TextView shop;
public TextView date;
public TextView price;
public TextView points;
}
public Object getFilter() {
// XXX Auto-generated method stub
return null;
}
}
--EDITAR:
Solução alternativa encontrada
Apenas para ter algum código funcional que eu faço agora:
listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);
Funciona, mas não como deve funcionar.
Respostas:
Mude o seu método de
Para
Portanto, você mantém o mesmo objeto que seu DataSet no seu adaptador.
fonte
ReceiptListObject
vez de umList
de objetos, o que você pode fazer para resolver esse problema?BaseAdapter
e este adaptador não sabe a quais dados ele está vinculado ... então, se eu tiver um objeto personalizado e usar funções personalizadas desse objeto (comocustObject.getCount()
ecustObject.getChildAt(int i)
por exemplo) e quiser trocar esse objeto,notifyDataSetChanged
não está funcionando ... de qualquer forma, acho que esse problema nunca ocorre com umArrayAdapter
Eu tenho o mesmo problema e percebo isso. Quando criamos o adaptador e o configuramos para listview, o listview apontará para um objeto em algum lugar na memória que o adaptador retém, os dados nesse objeto serão mostrados no listview.
se criarmos um objeto para o adaptador com outros dados novamente e notifydatasetchanged ():
isso não afetará os dados na exibição de lista porque a lista está apontando para um objeto diferente, esse objeto não sabe nada sobre o novo objeto no adaptador e notifyDataSetChanged () não afeta nada. Portanto, devemos alterar os dados no objeto e evitar criar um novo objeto novamente para o adaptador
fonte
Como já expliquei as razões por trás desse problema e também como lidar com isso em um segmento de resposta diferente, aqui . Ainda estou compartilhando o resumo da solução aqui.
Um dos principais motivos
notifyDataSetChanged()
não funcionará para você - é,Seu adaptador perde referência à sua lista .
Ao criar e adicionar uma nova lista ao arquivo
Adapter
. Sempre siga estas diretrizes:arrayList
declarando globalmente.arrayList
ele cuidará dele, mas nunca perderá a referência.adapter.clear()
earrayList.clear()
antes de realmente adicionar dados à lista), mas não definir o adaptador ou seja, se os novos dados são preenchidos noarrayList
que apenasadapter.notifyDataSetChanged()
Espero que isto ajude.
fonte
Talvez tente atualizar seu ListView:
receiptsListView.invalidate()
.Edição: Outro pensamento veio à minha mente. Apenas para o registro, tente desativar o cache da exibição de lista:
fonte
Eu tive o mesmo problema usando
ListAdapter
Eu deixei o Android Studio implementar métodos para mim e é isso que eu tenho:
O problema é que esses métodos não chamam
super
implementações, portantonotifyDataSetChange
nunca são chamados.Remova essas substituições manualmente ou adicione super chamadas e deve funcionar novamente.
fonte
Podes tentar. Funciona para mim
fonte
Se
adapter
estiver definido comoAutoCompleteTextView
entãonotifyDataSetChanged()
não funciona.Precisa disso para atualizar o adaptador:
Consulte: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html
fonte
Se por acaso você aterrissou nesse tópico e se perguntou por que
adapter.invaidate()
ou osadapter.clear()
métodos não estão presentes no seu caso, talvez porque você possa estar usando, eRecyclerView.Adapter
não oBaseAdapter
que é usado pelo autor da pergunta. Se limparlist
ouarraylist
não resolver o seu problema, pode acontecer que você esteja executando duas ou mais instâncias do exemplo,adapter
por exemplo:Atividade principal
e
SomeFragment
Se, no segundo caso, você estiver esperando uma alteração na lista de visualizações infladas no modo de exibição do reciclador, isso não acontecerá, pois na segunda vez em que uma nova instância do
adapter
é criada, que não está anexada ao modo de exibição do reciclador. A configuraçãonotifyDataSetChanged
no segundo adaptador não alterará o conteúdo da exibição da recicla. Para isso, crie uma nova instância da visualização do reciclador em SomeFragment e anexe-a à nova instância do adaptador.SomeFragment
No entanto, não recomendo criar várias instâncias da mesma exibição de adaptador e reciclador.
fonte
Adicione este código
fonte
Eu tenho o mesmo problema, mas acabei de terminar !!
você deveria mudar para
fonte
Meu caso foi diferente, mas pode ser o mesmo para outros
para aqueles que ainda não conseguiram encontrar uma solução e tentaram tudo acima, se você estiver usando o adaptador dentro do fragmento, o motivo pelo qual ele não está funcionando
fragment could be recreating so the adapter is recreating everytime the fragment recreate
você deve verificar se o adaptador e a lista de objetos são nulos antes de inicializar
fonte