studio recyclerview personalizado llenar lista how elementos agregar actualizar android android-listview notifydatasetchanged

recyclerview - listview android personalizado



Android ListView no se actualiza después de notifyDataSetChanged (11)

En onResume () cambie esta línea

items = dbHelper.getItems(); //reload the items from database

a

items.addAll(dbHelper.getItems()); //reload the items from database

El problema es que nunca le dices a tu adaptador sobre la nueva lista de elementos. Si no desea pasar una nueva lista a su adaptador (como parece que no), simplemente use items.addAll después de su clear() . Esto asegurará que esté modificando la misma lista a la que hace referencia el adaptador.

Mi código ListFragment

public class ItemFragment extends ListFragment { private DatabaseHandler dbHelper; private static final String TITLE = "Items"; private static final String LOG_TAG = "debugger"; private ItemAdapter adapter; private List<Item> items; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.item_fragment_list, container, false); return view; } @Override public void onCreate(Bundle savedInstanceState) { super.setHasOptionsMenu(true); super.onCreate(savedInstanceState); getActivity().setTitle(TITLE); dbHelper = new DatabaseHandler(getActivity()); items = dbHelper.getItems(); adapter = new ItemAdapter(getActivity().getApplicationContext(), items); this.setListAdapter(adapter); } @Override public void onResume() { super.onResume(); items.clear(); items = dbHelper.getItems(); //reload the items from database adapter.notifyDataSetChanged(); } @Override public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); if(dbHelper != null) { //item is edited Item item = (Item) this.getListAdapter().getItem(position); Intent intent = new Intent(getActivity(), AddItemActivity.class); intent.putExtra(IntentConstants.ITEM, item); startActivity(intent); } } }

Mi ListView

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>

Pero esto no actualiza el ListView . Incluso después de reiniciar la aplicación, los elementos actualizados no se muestran. My ItemAdapter amplía BaseAdapter

public class ItemAdapter extends BaseAdapter{ private LayoutInflater inflater; private List<Item> items; private Context context; public ProjectListItemAdapter(Context context, List<Item> items) { super(); inflater = LayoutInflater.from(context); this.context = context; this.items = items; } @Override public int getCount() { return items.size(); } @Override public Object getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ItemViewHolder holder = null; if(convertView == null) { holder = new ItemViewHolder(); convertView = inflater.inflate(R.layout.list_item, parent,false); holder.itemName = (TextView) convertView.findViewById(R.id.topText); holder.itemLocation = (TextView) convertView.findViewById(R.id.bottomText); convertView.setTag(holder); } else { holder = (ItemViewHolder) convertView.getTag(); } holder.itemName.setText("Name: " + items.get(position).getName()); holder.itemLocation.setText("Location: " + items.get(position).getLocation()); if(position % 2 == 0) { convertView.setBackgroundColor(context.getResources().getColor(R.color.evenRowColor)); } else { convertView.setBackgroundColor(context.getResources().getColor(R.color.oddRowColor)); } return convertView; } private static class ItemViewHolder { TextView itemName; TextView itemLocation; } }

¿Puede alguien ayudar, por favor?


Está asignando elementos recargados a elementos de variables globales en onResume() , pero esto no se reflejará en la clase ItemAdapter , ya que tiene su propia variable de instancia llamada ''items''.

Para actualizar ListView , agregue una actualización () en la clase ItemAdapter que acepta datos de la lista, es decir, elementos

class ItemAdapter { ..... public void refresh(List<Item> items) { this.items = items; notifyDataSetChanged(); } }

actualizar onResume() con el siguiente código

@Override public void onResume() { super.onResume(); items.clear(); items = dbHelper.getItems(); //reload the items from database **adapter.refresh(items);** }


Mire su método ItemFragment en ItemFragment :

@Override public void onResume() { super.onResume(); items.clear(); items = dbHelper.getItems(); // reload the items from database adapter.notifyDataSetChanged(); }

lo que acaba de actualizar antes de llamar a notifyDataSetChanged() no es el campo private List<Item> items; del adaptador elementos de private List<Item> items; pero el campo idénticamente declarado del fragmento. El adaptador aún almacena una referencia a la lista de elementos que pasó cuando creó el adaptador (por ejemplo, en el fragmento onCreate). La forma más corta (en el sentido de número de cambios) pero no elegante para hacer que su código se comporte como espera es simplemente reemplazar la línea:

items = dbHelper.getItems(); // reload the items from database

con

items.addAll(dbHelper.getItems()); // reload the items from database

Una solución más elegante:

1) eliminar elementos ítems de private List<Item> items; from ItemFragment - necesitamos mantener referencia a ellos solo en el adaptador

2) cambiar onCreate a:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setHasOptionsMenu(true); getActivity().setTitle(TITLE); dbHelper = new DatabaseHandler(getActivity()); adapter = new ItemAdapter(getActivity(), dbHelper.getItems()); setListAdapter(adapter); }

3) agregar método en ItemAdapter:

public void swapItems(List<Item> items) { this.items = items; notifyDataSetChanged(); }

4) cambie su onResume a:

@Override public void onResume() { super.onResume(); adapter.swapItems(dbHelper.getItems()); }


Prueba esto

@Override public void onResume() { super.onResume(); items.clear(); items = dbHelper.getItems(); //reload the items from database adapter = new ItemAdapter(getActivity(), items);//reload the items from database adapter.notifyDataSetChanged(); }


Pruebe de esta manera:

this.notifyDataSetChanged();

en lugar de:

adapter.notifyDataSetChanged();

notifyDataSetChanged() a ListView no a la clase de adaptador.


Si desea actualizar su lista de listas no importa si desea hacer eso en onResume() , onCreate() o en alguna otra función, lo primero que debe tener en cuenta es que no necesitará crear una nueva instancia del adaptador, vuelva a llenar las matrices con sus datos. La idea es algo similar a esto:

private ArrayList<String> titles; private MyListAdapter adapter; private ListView myListView; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); myListView = (ListView) findViewById(R.id.my_list); titles = new ArrayList<String>() for(int i =0; i<20;i++){ titles.add("Title "+i); } adapter = new MyListAdapter(this, titles); myListView.setAdapter(adapter); } @Override public void onResume(){ super.onResume(); // first clear the items and populate the new items titles.clear(); for(int i =0; i<20;i++){ titles.add("New Title "+i); } adapter.notifySetDataChanged(); }

Entonces, dependiendo de esa respuesta, debería usar la misma List<Item> en su Fragment . En su primera inicialización de adaptador, completa su lista con los elementos y configura el adaptador a su vista de lista. Después de eso, en cada cambio en sus artículos, debe borrar los valores de los elementos principales de la List<Item> items y luego rellenarlos nuevamente con sus nuevos elementos y llamar a notifySetDataChanged(); .

Asi es como funciona : ).


Si el adaptador ya está configurado, al configurarlo nuevamente no actualizará la vista de lista. En su lugar, primero compruebe si la vista de lista tiene un adaptador y luego llame al método apropiado.

Creo que no es una buena idea crear una nueva instancia del adaptador al configurar la vista de lista. En cambio, crea un objeto.

BuildingAdapter adapter = new BuildingAdapter(context); if(getListView().getAdapter() == null){ //Adapter not set yet. setListAdapter(adapter); } else{ //Already has an adapter adapter.notifyDataSetChanged(); }

También puede intentar ejecutar la lista de actualización en el subproceso UI:

activity.runOnUiThread(new Runnable() { public void run() { //do your modifications here // for example adapter.add(new Object()); adapter.notifyDataSetChanged() } });


Si su lista está contenida en el Adaptador mismo, llamar a la función que actualiza la lista también debe llamar a notifyDataSetChanged() .

Ejecutar esta función desde el subproceso UI me funcionó:

La función refresh() dentro del Adaptador

public void refresh(){ //manipulate list notifyDataSetChanged(); }

Luego, a su vez ejecuta esta función desde el subproceso UI

getActivity().runOnUiThread(new Runnable() { @Override public void run() { adapter.refresh() } });


Una respuesta de AlexGo hizo el truco para mí:

getActivity().runOnUiThread(new Runnable() { @Override public void run() { messages.add(m); adapter.notifyDataSetChanged(); getListView().setSelection(messages.size()-1); } });

La Actualización de lista me funcionó antes cuando la actualización se desencadenó a partir de un evento GUI, por lo que se encontraba en el hilo de la interfaz de usuario.

Sin embargo, cuando actualizo la lista desde otro evento / subproceso, es decir, una llamada desde fuera de la aplicación, la actualización no estaría en el hilo de la interfaz de usuario e ignoró la llamada a getListView. Llamar a la actualización con runOnUiThread como arriba hizo el truco para mí. ¡¡Gracias!!


adapter.setNotifyDataChanged()

debería hacer el truco.


adpter.notifyDataSetInvalidated();

Pruebe esto en el método onPause() de la clase Activity.