Search code examples
androidlistviewandroid-listviewonlongclicklistener

Refresh ListView after deletion


I checked a lot of stack overflow question, and none of them helped. How to refresh my listView after deleting item with onLongClickListener? As you'll see nor adapter.notifyDataSetChanged(), nor listView.invalidateViews() don't work.

This is implementation with just necessary methods to figure out idea.

public class MainActivity extends AppCompatActivity {
public FloatingActionButton fabAddWord;
public Toolbar toolbar;
public ListView listView;
private RjecnikCursorAdapter adapter;

private RjecnikDB dbRjecnik;
private SQLiteDatabase db;
private Cursor cursor;

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

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    fabAddWord = (FloatingActionButton) findViewById(R.id.fabAddWord);
    listView = (ListView) findViewById(R.id.listView);

    dbRjecnik = new RjecnikDB(this);
    db = dbRjecnik.getWritableDatabase();
    String query = "SELECT * FROM " + RjecnikDB.TABLE;
    cursor = db.rawQuery(query, null);

    adapter = new RjecnikCursorAdapter(this, cursor);
    listView.setAdapter(adapter);

    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            deleteOnLongClick(cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC)));

            adapter.notifyDataSetChanged();
            listView.invalidateViews();

            return true;
        }
    });
}

public void deleteOnLongClick(String rijec) {
    SQLiteDatabase db = dbRjecnik.getWritableDatabase();
    db.delete(RjecnikDB.TABLE, RjecnikDB.COLUMN_RIJEC + " = ?", new String[] {rijec} );

    this.adapter.notifyDataSetChanged();
    this.listView.invalidateViews();

    db.close();
}

CustomAdapter

public class RjecnikCursorAdapter extends CursorAdapter {

public RjecnikCursorAdapter (Context context, Cursor cursor) {
    super(context, cursor, 0);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return LayoutInflater.from(context).inflate(R.layout.item_word, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView tvSingleLineWord = (TextView) view.findViewById(R.id.tvSingleLineWord);

    // Extract properties from cursor
    String rijec = cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC));

    // Populate fields with extracted properties
    tvSingleLineWord.setText(rijec);
}

}


Solution

  • The Adapter have a data cache, so data in ListView will not change when data in database changed. You should change the cursor.

    @Override
    public void changeCursor(Cursor cursor) {
        mIndexer.setCursor(cursor);
        super.changeCursor(cursor);
    }
    

    put code below to your OnItemLongClickListener

    cursor = db.rawQuery(query, null);
    adapter.changeCurosr(cursor);