tutorial studio personalizado example ejemplo dinamico desplegable custom crear android listview baseadapter notifydatasetchanged

example - spinner personalizado android studio



notifyDataSetChange no funciona desde un adaptador personalizado (7)

Cambia tu método de

public void updateReceiptsList(List<Receipt> newlist) { receiptlist = newlist; this.notifyDataSetChanged(); }

A

public void updateReceiptsList(List<Receipt> newlist) { receiptlist.clear(); receiptlist.addAll(newlist); this.notifyDataSetChanged(); }

Así que mantienes el mismo objeto que tu DataSet en tu Adaptador.

Cuando repobulo mi ListView , llamo a un método específico de mi Adapter .

Problema :

Cuando llamo updateReceiptsList desde mi Adapter , los datos se actualizan, pero mi ListView no refleja el cambio.

Pregunta :

¿Por qué mi ListView muestra los datos nuevos 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 funciona.


Como ya he explicado las razones detrás de este problema y también cómo manejarlo en un hilo de respuesta diferente Here . Todavía estoy compartiendo el resumen de la solución aquí.

Una de las razones principales por las que notifyDataSetChanged() no funcionará para usted, es decir,

Su adaptador pierde referencia a su lista .

Al crear y agregar una nueva lista al Adapter . Siempre siga estas pautas:

  1. Inicialice el arrayList mientras lo declara globalmente.
  2. Agregue la lista al adaptador directamente sin verificar los valores nulos y vacíos. Configure el adaptador directamente en la lista (no verifique ninguna condición). El adaptador le garantiza que siempre que realice cambios en los datos de la lista de arrayList , se encargará de ello, pero nunca perderá la referencia.
  3. Siempre modifique los datos en el arrayList mismo (si sus datos son completamente nuevos, puede llamar a adapter.clear() y arrayList.clear() antes de agregar datos a la lista) pero no configure el adaptador, es decir, si los datos nuevos está poblado en la arrayList de arrayList que simplemente adapter.notifyDataSetChanged()

Espero que esto ayude.


Si el adapter está configurado en AutoCompleteTextView , notifyDataSetChanged() no funciona.

Necesito esto para actualizar el adaptador:

myAutoCompleteAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_dropdown_item_1line, myList); myAutoComplete.setAdapter(myAutoCompleteAdapter);

Consulte: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html


Tal vez 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:

<ListView ... android:scrollingCache="false" android:cacheColorHint="@android:color/transparent" ... />


Tengo el mismo problema, y ​​me doy cuenta de eso. Cuando creamos el adaptador y lo establecemos en listview, listview apuntará al objeto en algún lugar de la memoria que el adaptador contendrá, los datos en este objeto se mostrarán en la vista de lista.

adapter = new CustomAdapter(data); listview.setadapter(adapter);

si creamos un objeto para el adaptador con otra información de nuevo y notifydatasetchanged ():

adapter = new CustomAdapter(anotherdata); adapter.notifyDataSetChanged();

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. Entonces deberíamos cambiar los datos en el objeto y evitar crear un nuevo objeto nuevamente para el adaptador


Tuve el mismo problema al utilizar ListAdapter

Dejé que Android Studio implementara métodos para mí y esto es lo que obtuve:

public class CustomAdapter implements ListAdapter { ... @Override public void registerDataSetObserver(DataSetObserver observer) { } @Override public void unregisterDataSetObserver(DataSetObserver observer) { } ... }

El problema es que estos métodos no llaman super implementaciones, por lo que notifyDataSetChange nunca se llama.

Elimine estas anulaciones manualmente o agregue supercarrellas y debería funcionar de nuevo.

@Override public void registerDataSetObserver(DataSetObserver observer) { super.registerDataSetObserver(observer); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { super.unregisterDataSetObserver(observer); }


Agrega este código

runOnUiThread(new Runnable() { public void run() { adapter = new CustomAdapter(anotherdata); adapter.notifyDataSetChanged(); } });