Cuando vuelvo a llenar mi ListView
, llamo a un método específico desde mi Adapter
.
Problema :
Cuando llamo updateReceiptsList
desde mi Adapter
, los datos se actualizan, pero mi ListView
no refleja el cambio.
Pregunta :
¿Por qué mi no ListView
muestra los nuevos datos cuando llamo 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:
Solución encontrada
Solo para tener un código funcional que hago ahora:
listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);
Funciona, pero no cómo se supone que debe funcionar.
Respuestas:
Cambia tu método de
A
Así que mantienes el mismo objeto que tu DataSet en tu Adaptador.
fuente
ReceiptListObject
lugar de unoList
de objetos, ¿qué puede hacer para resolver este problema?BaseAdapter
ay este adaptador no sabe a qué datos está vinculado ... así que si tengo un objeto personalizado y uso funciones personalizadas de este objeto (comocustObject.getCount()
ycustObject.getChildAt(int i)
por ejemplo), y quiero intercambiar este objeto,notifyDataSetChanged
no funciona ... de todos modos, creo que este problema nunca ocurre con unArrayAdapter
Tengo el mismo problema, y me doy cuenta de eso. Cuando creamos un adaptador y lo configuramos en listview, listview apuntará a un objeto en algún lugar de la memoria que el adaptador contiene, los datos de este objeto se mostrarán en listview.
si volvemos a crear un objeto para adaptador con otros datos y te notificamos adatasetchanged ():
esto no afectará a los datos en la vista de lista porque la lista apunta a un objeto diferente, este objeto no sabe nada sobre el nuevo objeto en el adaptador, y notifyDataSetChanged () no afecta a nada. Por lo tanto, debemos cambiar los datos en el objeto y evitar crear un nuevo objeto nuevamente para el adaptador
fuente
Como ya he explicado las razones detrás de este problema y también cómo manejarlo en un hilo de respuesta diferente Aquí . Todavía estoy compartiendo el resumen de la solución aquí.
Una de las razones principales por las
notifyDataSetChanged()
que no funcionará es queSu adaptador pierde referencia a su lista .
Al crear y agregar una nueva lista a
Adapter
. Siempre siga estas pautas:arrayList
mientras lo declara globalmente.arrayList
mismo se encargará de ello, pero nunca perderá la referencia.adapter.clear()
yarrayList.clear()
antes de que realmente la adición de datos a la lista), pero no configurar el adaptador es decir, si los nuevos datos se rellena en elarrayList
que sóloadapter.notifyDataSetChanged()
Espero que esto ayude.
fuente
Quizás intente actualizar su ListView:
receiptsListView.invalidate()
.EDITAR: Otro pensamiento vino a mi mente. Solo para el registro, intente deshabilitar el caché de vista de lista:
fuente
Tuve el mismo problema usando
ListAdapter
Dejo que Android Studio implemente métodos para mí y esto es lo que obtuve:
El problema es que estos métodos no llaman a
super
implementaciones, pornotifyDataSetChange
lo que nunca se llama.Elimine estas anulaciones manualmente o agregue súper llamadas y debería funcionar nuevamente.
fuente
Puedes probar. Funciona para mi
fuente
Si
adapter
se establece en,AutoCompleteTextView
entoncesnotifyDataSetChanged()
no funciona.Necesita esto para actualizar el adaptador:
Consulte: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html
fuente
Si por casualidad llegaste a este hilo y te preguntas por qué
adapter.invaidate()
o losadapter.clear()
métodos no están presentes en tu caso, entonces tal vez porque podrías estar usando enRecyclerView.Adapter
lugar de loBaseAdapter
que usa el que hace la pregunta. Si borralist
oarraylist
no resuelve su problema, puede suceder que esté haciendo dos o más instancias deladapter
por ejemplo:Actividad principal
y
algún fragmento
Si en el segundo caso espera un cambio en la lista de vistas infladas en la vista del reciclador, entonces no sucederá, ya que en la segunda vez
adapter
se crea una nueva instancia de la que no está adjunta a la vista del reciclador. La configuraciónnotifyDataSetChanged
en el segundo adaptador no cambiará el contenido de la vista de reciclador. Para ello, cree una nueva instancia de la vista de reciclador en SomeFragment y adjúntela a la nueva instancia del adaptador.Algún fragmento
Sin embargo, no recomiendo hacer varias instancias del mismo adaptador y vista de reciclador.
fuente
Agrega este código
fuente
¡Tengo el mismo problema pero lo acabo de terminar!
deberías cambiar a
fuente
Mi caso era diferente pero podría ser el mismo para otros.
para aquellos que todavía no pudieron encontrar una solución y probaron todo lo anterior, si está utilizando el adaptador dentro del fragmento, entonces la razón no está funcionando
fragment could be recreating so the adapter is recreating everytime the fragment recreate
debe verificar si el adaptador y la lista de objetos son nulos antes de inicializar
fuente