¿Cómo actualizar la vista de lista de Android?

Respuestas:

530

Llame notifyDataSetChanged()a su Adapterobjeto una vez que haya modificado los datos en ese adaptador.

Algunos detalles adicionales sobre cómo / cuándo llamar notifyDataSetChanged()se pueden ver en el vídeo de Google I / O .

Christopher Orr
fuente
24
Debe ejecutarlo en el hilo de la interfaz de usuario. Cree un controlador dentro del hilo de la interfaz de usuario y luego publique Runable en él
Kirill Kulakov
11
Una vez más: notifyDataSetChanged () no funciona al menos para las prácticas de uso recomendadas (lectura no desaprobada). Si usa listview, adaptador de cursor y proveedor de contenido, puede intentar algo similar: gettLoaderManager (). RestartLoader (). Ver: stackoverflow.com/a/19657500/1087411 Me gustaría ver al menos algo de documentación en notifyDataSetChanged (). Mucho en Android se deja a prueba de caja negra.
Anderson
Si notifyDataSetChanged no funciona, usted es quien lo está haciendo mal
zdarsky.peter
44
notifyDataSetChanged no siempre funciona. No estoy seguro de por qué esto está en disputa. A veces tiene que llamar a listView.setAdapter (adaptador) para borrar las vistas anteriores. Consulte también: stackoverflow.com/a/16261588/153275
1
Nunca pude hacer que funcionen notifyDataSetChanged. Pude ver claramente que la colección que le proporciono al adaptador ha cambiado (se eliminaron los elementos), pero notifyDataSetChanged nunca ha hecho nada. ¿No está seguro si este método está roto?
byemute
204

También puedes usar esto:

myListView.invalidateViews();
Bobs
fuente
22
Esta es la respuesta correcta si solo es necesario REDUCIR la vista. Por ejemplo, después de que se produce un inicio de sesión de usuario que necesita exponer más información u opciones dentro de cada vista de listView. Eso es lo que necesitaba hacer, así que voté a favor. Si los datos subyacentes cambian, probablemente sea una mejor idea usar notifyDataSetChanged ().
SBerg413
En realidad, invalidateViews()en los conjuntos de código fuente, mDataChanged = true;así que no estoy seguro de si esto resulta en un mejor rendimiento en comparación connotifyDataSetChanged()
vovahost
¡Me salvaste el día, amigo!
oskarko
puede tomar un tipo de lista que es "lista observable", no es necesario notificar que el conjunto de datos ha cambiado
Priya
153

Por favor ignorar todos los invalidate(), invalidateViews(), requestLayout(), ... respuestas a esta pregunta.

Lo correcto (y afortunadamente también marcado como respuesta correcta) es llamar notifyDataSetChanged()a su adaptador .

Solución de problemas

Si las llamadas notifyDataSetChanged()no funcionan, todos los métodos de diseño tampoco ayudarán. Créeme, ListViewse actualizó correctamente. Si no encuentra la diferencia, debe verificar de dónde provienen los datos en su adaptador.

Si esto es solo una colección que está guardando en la memoria, compruebe que realmente eliminó o agregó los elementos a la colección antes de llamar al notifyDataSetChanged().

Si está trabajando con una base de datos o backend de servicio, deberá llamar al método para recuperar la información nuevamente (o manipular los datos en la memoria) antes de llamar al notifyDataSetChanged().

La cuestión es que esto notifyDataSetChangedsolo funciona si el conjunto de datos ha cambiado. Así que ese es el lugar para buscar si no encuentra cambios. Depurar si es necesario.

ArrayAdapter vs BaseAdapter

Descubrí que trabajar con un adaptador que le permite administrar la colección, como un Adaptador de Base, funciona mejor. Algunos adaptadores como el ArrayAdapter ya administran su propia colección, lo que hace que sea más difícil llegar a la colección adecuada para actualizaciones. En realidad, es solo una capa adicional innecesaria de dificultad en la mayoría de los casos.

Hilo de UI

Es cierto que esto debe llamarse desde el hilo de la interfaz de usuario. Otras respuestas tienen ejemplos sobre cómo lograr esto. Sin embargo, esto solo es necesario si está trabajando en esta información desde fuera del hilo de la interfaz de usuario. Eso es de un servicio o un subproceso no UI. En casos simples, actualizará sus datos con solo hacer clic en un botón u otra actividad / fragmento. Aún así dentro del hilo de la interfaz de usuario. No es necesario que siempre aparezca esa runOnUiTrhead.

Proyecto de ejemplo rápido

Se puede encontrar en https://github.com/hanscappelle/so-2250770.git . Simplemente clone y abra el proyecto en Android Studio (gradle). Este proyecto tiene un MainAcitivity construyendo un ListViewcon todos los datos aleatorios. Esta lista se puede actualizar utilizando el menú de acciones.

La implementación del adaptador que creé para este ejemplo ModelObject expone la recopilación de datos

public class MyListAdapter extends BaseAdapter {

    /**
     * this is our own collection of data, can be anything we 
     * want it to be as long as we get the abstract methods 
     * implemented using this data and work on this data 
     * (see getter) you should be fine
     */
    private List<ModelObject> mData;

    /**
     * our ctor for this adapter, we'll accept all the things 
     * we need here
     *
     * @param mData
     */
    public MyListAdapter(final Context context, final List<ModelObject> mData) {
        this.mData = mData;
        this.mContext = context;
    }

    public List<ModelObject> getData() {
        return mData;
    }

    // implement all abstract methods here
}

Código de MainActivity

public class MainActivity extends Activity {

    private MyListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView list = (ListView) findViewById(R.id.list);

        // create some dummy data here
        List<ModelObject> objects = getRandomData();
        // and put it into an adapter for the list
        mAdapter = new MyListAdapter(this, objects);
        list.setAdapter(mAdapter);

        // mAdapter is available in the helper methods below and the 
        // data will be updated based on action menu interactions

        // you could also keep the reference to the android ListView 
        // object instead and use the {@link ListView#getAdapter()} 
        // method instead. However you would have to cast that adapter 
        // to your own instance every time
    }

    /**
     * helper to show what happens when all data is new
     */
    private void reloadAllData(){
        // get new modified random data
        List<ModelObject> objects = getRandomData();
        // update data in our adapter
        mAdapter.getData().clear();
        mAdapter.getData().addAll(objects);
        // fire the event
        mAdapter.notifyDataSetChanged();
    }

    /**
     * helper to show how only changing properties of data 
     * elements also works
     */
    private void scrambleChecked(){
        Random random = new Random();
        // update data in our adapter, iterate all objects and 
        // resetting the checked option
        for( ModelObject mo : mAdapter.getData()) {
            mo.setChecked(random.nextBoolean());
        }
        // fire the event
        mAdapter.notifyDataSetChanged();
    }
}

Más información

Otra buena publicación sobre el poder de listViews se encuentra aquí: http://www.vogella.com/articles/AndroidListView/article.html

hcpl
fuente
16
te equivocas. notifyDataSetChanged () no funcionó para mí, pero invalidateViews () lo hizo bien.
babay
66
Tengo el problema de que los elementos reales de la lista no cambian, por ejemplo, la misma cantidad de elementos. Pero el problema es que la forma en que se presentan debe cambiar. Eso significa que el código de mi adaptador para construir la interfaz de usuario debe ejecutarse nuevamente y luego ocultar correctamente algún elemento en las filas de la lista. notifyDataSetChanged () no funciona ...
Sven Haiges
99
Esta respuesta realmente me ayudó. Estaba manteniendo la matriz en la memoria por ciertas razones. Para solucionarlo, ahora llamo adapter.clear(), y adapter.addAll(Array<T>)antes de llamarnotifyDataSetChanged()
Michael DePhillips,
2
@hcpl, ¿cómo debo llamar a notifyDataSetChanged si estoy en OnClickListener del adaptador para un CheckBox? invalidateViews está haciendo el trabajo ahora mismo. ¿Por qué invalidateViews es el método incorrecto para llamar?
Craned
1
Nunca pude hacer que funcionen notifyDataSetChanged. Pude ver claramente que la colección que le proporciono al adaptador ha cambiado (se eliminaron los elementos), pero notifyDataSetChanged nunca ha hecho nada. ¿No está seguro si este método está roto?
byemute
42

Llamada ejecutable cuando quieras:

runOnUiThread(run);

OnCreate(), configura su hilo ejecutable:

run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};
Marckaraujo
fuente
1
Trabajando también en mi caso, donde necesito actualizar una vista de lista basada en datos provenientes de una conexión TCP (de un hilo "no UI"). La única forma de volver a dibujar la lista era borrar y volver a agregar todos los elementos de ArrayList. De todos modos, si ya está en el hilo de la interfaz de usuario, no necesita llamar al código a través de la runOnUiThread()función.
Andre
¡Gracias! Esto funciona para mi. Para todas las personas que desean ejecutar esto desde un fragmento, debe usar getActivity (). RunOnUiThread (nuevo Runnable ... para asegurarse de que el código se ejecute en el hilo de la interfaz de usuario
codingpuss
No veo el propósito run = new Runnable()y simplemente le di a mi función un public void refreshUIThread()método que modela su run()método (que también funciona).
T.Woody
11

Tengo algunos problemas con la actualización dinámica de mi vista de lista.

Llame a notifyDataSetChanged () en su adaptador.

En este video de Google I / O se pueden ver algunos detalles adicionales sobre cómo / cuándo llamar a notifyDataSetChanged ().

notifyDataSetChanged () no funcionó correctamente en mi caso [llamé a notifyDataSetChanged de otra clase]. Solo en el caso de que edité el ListView en la Actividad en ejecución (Hilo). Ese video gracias a Christopher dio la pista final.

En mi segunda clase solía

Runnable run = new Runnable(){
     public void run(){
         contactsActivity.update();
     }
};
contactsActivity.runOnUiThread(run);

para acceder a la actualización () desde mi Actividad. Esta actualización incluye

myAdapter.notifyDataSetChanged();

para decirle al adaptador que actualice la vista. Funcionó bien hasta donde puedo decir.

Wille
fuente
5

si aún no está satisfecho con el Refresco ListView, puede ver este fragmento, esto es para cargar listView desde DB, en realidad lo que tiene que hacer es simplemente volver a cargar ListView, después de realizar cualquier Operación CRUD No es la mejor manera de código, pero actualizará el ListView como desee.

Funciona para mí ... si encuentras una mejor solución, comparte ...

.......
......
hacer sus operaciones CRUD ..
......
.....
DBAdapter.open ();
DBAdapter.insert_into_SingleList ();
// Trae esos resultados DB_ y agrégalos a la lista como su contenido ...
                                            ls2.setAdapter (nuevo ArrayAdapter (DynTABSample.this,
    android.R.layout.simple_list_item_1, DBAdapter.DB_ListView));
                                            DBAdapter.close ();
Nandagopal T
fuente
2

Las soluciones propuestas por las personas en esta publicación funcionan o no principalmente según la versión de Android de su dispositivo. Por ejemplo, para usar el método AddAll, debe poner android: minSdkVersion = "10" en su dispositivo Android.

Para resolver estas preguntas para todos los dispositivos, he creado mi propio método en mi adaptador y lo uso dentro del método de agregar y quitar hereda de ArrayAdapter que actualiza sus datos sin problemas.

Mi código: usando mi propia clase de datos RaceResult, usted usa su propio modelo de datos.

ResultGpRowAdapter.java

public class ResultGpRowAdapter extends ArrayAdapter<RaceResult> {

    Context context;
    int resource;
    List<RaceResult> data=null;

        public ResultGpRowAdapter(Context context, int resource, List<RaceResult> objects)           {
        super(context, resource, objects);

        this.context = context;
        this.resource = resource;
        this.data = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ........
        }

        //my own method to populate data           
        public void myAddAll(List<RaceResult> items) {

        for (RaceResult item:items){
            super.add(item);
        }
    }

ResultsGp.java

public class ResultsGp extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...........
    ...........
    ListView list = (ListView)findViewById(R.id.resultsGpList); 

    ResultGpRowAdapter adapter = new ResultGpRowAdapter(this,  R.layout.activity_result_gp_row, new ArrayList<RaceResult>()); //Empty data

   list.setAdapter(adapter);

   .... 
   ....
   ....
   //LOAD a ArrayList<RaceResult> with data

   ArrayList<RaceResult> data = new ArrayList<RaceResult>();
   data.add(new RaceResult(....));
   data.add(new RaceResult(....));
   .......

   adapter.myAddAll(data); //Your list will be udpdated!!!
AntuanSoft
fuente
1

Si desea mantener su posición de desplazamiento cuando actualiza, y puede hacer esto:

if (mEventListView.getAdapter() == null) {
    EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
    mEventListView.setAdapter(eventLogAdapter);
} else {
    ((EventLogAdapter)mEventListView.getAdapter()).refill(events);
}

public void refill(List<EventLog> events) {
    mEvents.clear();
    mEvents.addAll(events);
    notifyDataSetChanged();
}

Para obtener información detallada, consulte Android ListView: mantenga su posición de desplazamiento cuando actualice .

Brandon Yang
fuente
1

Solo use myArrayList.remove(position);dentro de un oyente:

  myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override public void onItemClick(AdapterView<?> parent, android.view.View view, int position, long id) {
           myArrayList.remove(position);
           myArrayAdapter.notifyDataSetChanged();
        }
    });
Steffo Dimfelt
fuente
1

Debe usar un solo objeto de esa lista cuyos datos está inflando ListView. Si la referencia es un cambio, entonces no notifyDataSetChanged()funciona. Siempre que esté eliminando elementos de la vista de lista, también elimínelos de la lista que está utilizando, ya sea una ArrayList <> o Algo más, luego llame notifyDataSetChanged()al objeto de Su clase de adaptador.

Entonces, vea cómo lo administré en mi adaptador, vea a continuación

public class CountryCodeListAdapter extends BaseAdapter implements OnItemClickListener{

private Context context;
private ArrayList<CountryDataObject> dObj;
private ViewHolder holder;
private Typeface itemFont;
private int selectedPosition=-1;
private ArrayList<CountryDataObject> completeList;

public CountryCodeListAdapter(Context context, ArrayList<CountryDataObject> dObj) {
    this.context = context;
    this.dObj=dObj;
    completeList=new  ArrayList<CountryDataObject>();
    completeList.addAll(dObj);
    itemFont=Typeface.createFromAsset(context.getAssets(), "CaviarDreams.ttf");
}

@Override
public int getCount() {
    return dObj.size();
}

@Override
public Object getItem(int position) {
    return dObj.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
    if(view==null){
        holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.states_inflator_layout, null);
        holder.textView = ((TextView)view.findViewById(R.id.stateNameInflator));
        holder.checkImg=(ImageView)view.findViewById(R.id.checkBoxState);
        view.setTag(holder);
    }else{
        holder = (ViewHolder) view.getTag();
    }
    holder.textView.setText(dObj.get(position).getCountryName());
    holder.textView.setTypeface(itemFont);

    if(position==selectedPosition)
     {
         holder.checkImg.setImageResource(R.drawable.check);
     }
     else
     {
         holder.checkImg.setImageResource(R.drawable.uncheck);
     }
    return view;
}
private class ViewHolder{
    private TextView textView;
    private ImageView checkImg;
}

public void getFilter(String name) {
    dObj.clear();
    if(!name.equals("")){
    for (CountryDataObject item : completeList) {
        if(item.getCountryName().toLowerCase().startsWith(name.toLowerCase(),0)){
            dObj.add(item);
        }
    }
    }
    else {
        dObj.addAll(completeList);
    }
    selectedPosition=-1;
    notifyDataSetChanged();
    notifyDataSetInvalidated(); 
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    Registration reg=(Registration)context;
    selectedPosition=position;
    reg.setSelectedCountryCode("+"+dObj.get(position).getCountryCode());
    notifyDataSetChanged();
}
}
ADM
fuente
1
su explicación está subestimada, pero realmente me da comprensión sobre la referencia de la lista de arrays gracias
Abraham Putra Prakasa
0

Después de eliminar datos de la vista de lista, debe llamar refreshDrawableState(). Aquí está el ejemplo:

final DatabaseHelper db = new DatabaseHelper (ActivityName.this);

db.open();

db.deleteContact(arg3);

mListView.refreshDrawableState();

db.close();

y el deleteContactmétodo en DatabaseHelperclase será algo parecido

public boolean deleteContact(long rowId) {

   return db.delete(TABLE_NAME, BaseColumns._ID + "=" + rowId, null) > 0;

}
usuario1031852
fuente
0

No pude obtener notifyDataSetChanged () para trabajar en la actualización de mi SimpleAdapter, por lo que primero intenté eliminar todas las vistas que estaban adjuntas al diseño principal usando removeAllViews (), luego agregué ListView y funcionó, lo que me permitió actualizar el Interfaz de usuario:

LinearLayout results = (LinearLayout)findViewById(R.id.results);
ListView lv = new ListView(this);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter( this, list, R.layout.directory_row, 
                new String[] { "name", "dept" }, new int[] { R.id.name, R.id.dept } );

for (...) { 
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    map.put("dept", dept);
    list.add(map);
}

lv.setAdapter(adapter);
results.removeAllViews();     
results.addView(lv);
Chasden
fuente
0

Para mí, después de cambiar la información en la base de datos sql, nada podría actualizar la vista de lista (para ser una vista de lista expandible específica), por lo que si notifyDataSetChanged () no ayuda, puede intentar borrar su lista primero y agregarla nuevamente después de esa llamada notifyDataSetChanged (). Por ejemplo

private List<List<SomeNewArray>> arrayList;
List<SomeNewArray> array1= getArrayList(...);
List<SomeNewArray> array2= getArrayList(...);
arrayList.clear();
arrayList.add(array1);
arrayList.add(array2);
notifyDataSetChanged();

Espero que tenga sentido para ti.

Aivus
fuente
0

mientras usa SimpleCursorAdapter puede llamar a changeCursor (newCursor) en el adaptador.

Vihaan Verma
fuente
0

Era igual cuando, en un fragmento, quería llenar un ListView (en un único TextView) con la dirección mac de los dispositivos BLE escaneados durante algún tiempo.

Lo que hice fue esto:

public class Fragment01 extends android.support.v4.app.Fragment implements ...
{
    private ListView                listView;
    private ArrayAdapter<String>    arrayAdapter_string;

...

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    ...
    this.listView= (ListView) super.getActivity().findViewById(R.id.fragment01_listView);
    ...
    this.arrayAdapter_string= new ArrayAdapter<String>(super.getActivity(), R.layout.dispositivo_ble_item, R.id.fragment01_item_textView_titulo);
    this.listView.setAdapter(this.arrayAdapter_string);
}


@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
    ...
    super.getActivity().runOnUiThread(new RefreshListView(device));
}


private class RefreshListView implements Runnable
{
    private BluetoothDevice bluetoothDevice;

    public RefreshListView(BluetoothDevice bluetoothDevice)
    {
        this.bluetoothDevice= bluetoothDevice;
    }

    @Override
    public void run()
    {
        Fragment01.this.arrayAdapter_string.add(new String(bluetoothDevice.toString()));
        Fragment01.this.arrayAdapter_string.notifyDataSetChanged();
    }
}

Luego, ListView comenzó a llenarse dinámicamente con la dirección mac de los dispositivos encontrados.

jsanmarb
fuente
0

Creo que depende de lo que quieras decir con refrescar. ¿Quiere decir que la pantalla GUI debe actualizarse o quiere decir que las vistas secundarias deben actualizarse de manera que pueda llamar programáticamente a getChildAt (int) y obtener la vista correspondiente a lo que está en el Adaptador?

Si desea que se actualice la pantalla de la GUI, llame a notifyDataSetChanged () en el adaptador. La GUI se actualizará la próxima vez que se vuelva a dibujar.

Si desea poder llamar a getChildAt (int) y obtener una vista que refleje qué es lo que hay en el adaptador, llame a layoutChildren (). Esto hará que la vista secundaria se reconstruya a partir de los datos del adaptador.

aturdido
fuente
0

Tenía una ArrayList que quería mostrar en una vista de lista. ArrayList contenía elementos de mysql. Anulé el método de actualización y en ese método usé tablelayout.removeAllViews (); y luego repitió el proceso para obtener datos nuevamente de la base de datos. Pero antes de eso, asegúrese de borrar su ArrayList o cualquier estructura de datos o, de lo contrario, se agregarán datos nuevos al anterior.

Kshitij G
fuente
0

Si desea actualizar la vista de lista de la interfaz de usuario de un servicio, haga que el adaptador esté estático en su actividad Principal y haga esto:

@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    
Mayank Saini
fuente
0

Si utiliza las líneas de guía de Android y está utilizando el ContentProviderspara obtener datos Databasey lo está mostrando en el ListViewuso de CursorLoadery CursorAdapters, todos los cambios en los datos relacionados se reflejarán automáticamente en el ListView.

Su getContext().getContentResolver().notifyChange(uri, null);en el cursor en el ContentProviderserá suficiente para reflejar los cambios. No es necesario el trabajo extra.

Pero cuando no está utilizando todo esto, debe informar al adaptador cuando el conjunto de datos está cambiando. También debe volver a llenar / recargar su conjunto de datos (por ejemplo, la lista) y luego debe llamar notifyDataSetChanged()al adaptador.

notifyDataSetChanged()no funcionará si no hay cambios en el conjunto de datos. Aquí está el comentario sobre el método en docs-

/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */
Sanjeet A
fuente
0

Solo pude obtener notifyDataSetChanged solo al obtener nuevos datos del adaptador, luego restablecí el adaptador para la vista de lista y luego hice la llamada de esta manera:

    expandableAdapter = baseFragmentParent.setupEXLVAdapter();
    baseFragmentParent.setAdapter(expandableAdapter);
    expandableAdapter.notifyDataSetChanged(); 
Kristy Welsh
fuente
0

en otra opción es el onWindowFocusChangedmétodo, pero seguro es sensible y necesita un poco de codificación adicional

 override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)

       // some controls needed
        programList = usersDBHelper.readProgram(model.title!!)
        notesAdapter = DailyAdapter(this, programList)
        notesAdapter.notifyDataSetChanged()
        listview_act_daily.adapter = notesAdapter
    }
Sam
fuente
0

Considere que ha pasado una lista a su adaptador.
Utilizar:

list.getAdapter().notifyDataSetChanged()

para actualizar tu lista.

Mahdi-Malv
fuente
0

Si hablé sobre mi escenario aquí, ninguna de las respuestas anteriores funcionará porque tuve una actividad que muestra una lista de valores de db junto con un botón Eliminar y cuando se presiona un botón Eliminar, quería eliminar ese elemento de la lista.

Lo bueno fue que no utilicé la vista de reciclador, sino una vista de lista simple y esa vista de lista inicializada en la clase de adaptador. Por lo tanto, llamar al notifyDataSetChanged()no hará nada dentro de la clase de adaptador e incluso en la clase de actividad donde se inicializa el objeto del adaptador porque el método de eliminación estaba en la clase del adaptador.

Entonces, la solución fue eliminar el objeto del adaptador en el getViewmétodo de clase de adaptador (para eliminar solo ese objeto específico, pero si desea eliminar todo, llame clear()).

Para que te hagas una idea, cómo era mi código,

public class WordAdapter extends ArrayAdapter<Word> {
  Context context;

  public WordAdapter(Activity context, ArrayList<Word> words) {}
    //.......

    @NonNull
    @Override
    public View getView(final int position, View convertView, ViewGroup group) {
      //.......
     ImageButton deleteBt = listItemView.findViewById(R.id.word_delete_bt);
     deleteBt.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             if (vocabDb.deleteWord(currentWord.id)) {
                //.....
             } else{
                //.....
             }
             remove(getItem(position)); // <---- here is the trick ---<
             //clear() // if you want to clear everything
         }
    });
 //....

Nota: aquí remove()y los getItem()métodos se heredan de la clase Adaptador.

  • remove() - para eliminar el elemento específico en el que se hace clic
  • getItem(position) - es para obtener el elemento (aquí, ese es mi objeto de Word que he agregado a la lista) desde la posición en la que se hizo clic.

Así es como configuro el adaptador para la vista de lista en la clase de actividad,

    ArrayList<Word> wordList = new ArrayList();
    WordAdapter adapter = new WordAdapter(this, wordList);

    ListView list_view = (ListView) findViewById(R.id.activity_view_words);
    list_view.setAdapter(adapter);
Blasanka
fuente
-1

Lo más fácil es hacer un nuevo Adaper y soltar el viejo:

myListView.setAdapter(new MyListAdapter(...));
usuario1712200
fuente
Esto consume más memoria.
Jugador1
la basura se recogerá
user1712200