Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to asynchronously delete a ListView/RecyclerView item

I have a ListView with a CursorLoader. The user can open ListView items (open another Fragment) or delete items. All database actions occur asynchronously and usually it takes a fraction of a second. But technically the user could delete an item and then open the item before the deletion callback and cause and error. What's the best way to handle this? Here are the options I see.

  1. Just assume that the AsyncTask will always happen quickly enough to avoid a problem
  2. Do the database operation on the UI thread
  3. Invalidate the ListView before the AsyncTask (but this would cause a flash in the UI)
  4. Block user input somehow during the AsyncTask

Edit: I ended up using RecyclerView but I can't call adapter.notifyItemRemoved(itemPos) until after I have deleted the item from the database.

like image 512
cambunctious Avatar asked Apr 03 '16 19:04

cambunctious


1 Answers

Best option in your case will be using RecyclerView. Because when you clicked delete you can call adapter.notifyItemRemoved(itemPos). So the list item will be removed with animation from your RecyclerView and you will not worry about the delete operation result.

See the Android Developer tutorial on Creating Lists and Cards:

Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events.

Here is an example:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener, View.OnLongClickListener {

private ArrayList<String> mDataset;
private static Context sContext;

public MyAdapter(Context context, ArrayList<String> myDataset) {
    mDataset = myDataset;
    sContext = context;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);

    ViewHolder holder = new ViewHolder(v);
    holder.mNameTextView.setOnClickListener(MyAdapter.this);

    holder.mNameTextView.setTag(holder);

    return holder;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    holder.mNameTextView.setText(mDataset.get(position));

}

@Override
public int getItemCount() {
    return mDataset.size();
}


@Override
public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    if (view.getId() == holder.mNameTextView.getId()) {
        **//Important !!!**
        notifyItemRemoved(getPosition());
        // Make your database operation also here
    }
}



public static class ViewHolder extends RecyclerView.ViewHolder {
    public TextView mNumberRowTextView;
    public TextView mNameTextView;


    public ViewHolder(View v) {
        super(v);

        mNameTextView = (TextView) v.findViewById(R.id.nameTextView);
    }
}
like image 194
Emin Ayar Avatar answered Sep 19 '22 20:09

Emin Ayar