How to update recyclerView after updating data via dialog

Asked

Viewed 1,670 times

1

My app works more or less like this.

Inside a fragment I have a Recyclerview composed of cardviews, fed by a database.

On each card, there is an edit button (imageView) that opens a dialog (alertDialog) with a form. of editing. Everything is working except the reclyclerview update.

Below the recyclerview adapter

import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; 

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {

private Context context;
private List<RunData> dataList = new ArrayList<>();
private LayoutInflater inflater;
private RunDbHelper runDbHelper; // db model helper class 

RecyclerViewAdapter(Context context, List<RunData> dataList1) {

    this.context = context;
    this.dataList = dataList1;
    this.runDbHelper = RunDbHelper.getInstance(this.context);
    inflater = LayoutInflater.from(context);
}

@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View inflateView = inflater.inflate(R.layout.fragment_recycler_row, parent, false);
    return new RecyclerViewHolder(inflateView);
}

// Parse data from dataList to holder and setup all Views
// Here is part of the magic
@Override
public void onBindViewHolder(final RecyclerViewHolder holder, final int position) {

    holder.runID.setText(dataList.get(position).run_id);
    holder.collectAddress.setText(dataList.get(position).collect_address);
    holder.collectPerson.setText(dataList.get(position).collect_person);
    holder.runParcel.setText(dataList.get(position).run_parcel);
    holder.deliveryAddress.setText(dataList.get(position).delivery_address);
    holder.deliveryPerson.setText(dataList.get(position).delivery_person);        

    holder.ivEdit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            RunData runData = new RunData(); // helper class to deal with one data row mirrors model
            runData.collect_address = holder.collectAddress.getText().toString();
            runData.collect_person = holder.collectPerson.getText().toString();
            runData.delivery_address = holder.deliveryAddress.getText().toString();
            runData.delivery_person = holder.deliveryPerson.getText().toString();
            runData.run_id = holder.runID.getText().toString();
            dialogEditRun(runData);
        }

    });

}

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

public void dialogEditRun(RunData runData) {

    // Get the Activity for layout inflater as this dialog runs inside a fragment
    LayoutInflater inflater = LayoutInflater.from(context);
    final View inflaterView = inflater.inflate(R.layout.dialog_edit_run, null);
    // Data entry field objects
    final EditText runParcelEditText = (EditText) inflaterView.findViewById(R.id.editRunParcel);
    final AutoCompleteTextView collectAddressACTV = (AutoCompleteTextView) inflaterView.findViewById(R.id.actvEditCollectAddress);
    final EditText collectPersonEditText = (EditText) inflaterView.findViewById(R.id.editCollectPerson);
    final AutoCompleteTextView deliveryAddressACTV = (AutoCompleteTextView) inflaterView.findViewById(R.id.actvEditDeliveryAddress);
    final EditText deliveryPersonEditText = (EditText) inflaterView.findViewById(R.id.editDeliveryPerson);
    final String mRunID;
    // get values from database and set edit values
    runParcelEditText.setText(runData.run_parcel);
    collectAddressACTV.setText(runData.collect_address);
    deliveryAddressACTV.setText(runData.delivery_address);
    collectPersonEditText.setText(runData.collect_person);
    deliveryPersonEditText.setText(runData.delivery_person);
    mRunID = runData.run_id;

    // Dialog Builder
    AlertDialog.Builder editRunDialog = new AlertDialog.Builder(context);
    editRunDialog.setTitle(R.string.dialog_update_run_title)
        .setView(inflaterView);

    editRunDialog.setPositiveButton(R.string.button_positive, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int id) {

            RunData runData = new RunData();
            runData.run_parcel = getStringOrEmpty(runParcelEditText);
            runData.collect_address = getStringOrEmpty(collectAddressACTV);
            runData.delivery_address = getStringOrEmpty(deliveryAddressACTV);
            runData.collect_person = getStringOrEmpty(collectPersonEditText);
            runData.delivery_person = getStringOrEmpty(deliveryPersonEditText);
            runData.run_id = mRunID;



            if (!(runData.collect_address.isEmpty() && runData.delivery_address.isEmpty())){
                // try to update, if success update recycler.
                if (runDbHelper.updateRun(runData, context)){ 
                // when true, update successfull
                // now, update recyclerview

                } else {
                    Toast.makeText(context, "Record not updated. try again", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(context, R.string.dialog_insert_run_toast_nowhere, Toast.LENGTH_SHORT).show();
            }
        }
    });

    editRunDialog.setNegativeButton(R.string.button_negative, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });

    editRunDialog.create();
    editRunDialog.show();

}

private String getStringOrEmpty(EditText editText) {
    String mString = editText.getText().toString();
    mString = (mString.isEmpty() ? "" : mString);
    return mString;
}

class RecyclerViewHolder extends RecyclerView.ViewHolder {
    TextView runID, collectPerson, collectAddress, deliveryPerson, deliveryAddress, runParcel;
    ImageView ivEdit;


    RecyclerViewHolder(View rowView) {
        super(rowView);
        runID = (TextView) rowView.findViewById(R.id.runId);
        collectAddress = (TextView) rowView.findViewById(R.id.collectAddress);
        collectPerson = (TextView) rowView.findViewById(R.id.collectPerson);
        runParcel = (TextView) rowView.findViewById(R.id.runParcel);
        deliveryAddress = (TextView) rowView.findViewById(R.id.deliveryAddress);
        deliveryPerson = (TextView) rowView.findViewById(R.id.deliveryPerson);
        ivEdit = (ImageView) rowView.findViewById(R.id.ivEdit);
    }
}

}

And now? Who can save us???

2 answers

3


If you want to insert or remove items within the Adapter, you will need to explicitly inform you that there has been a change. This is slightly different from notifyDataSetChanged(). Just create two insertion and removal methods.

public void add(RunData item, int position) {
    items.add(position, item);
    notifyItemInserted(position);
}

public void remove(RunData item) {
    int position = items.indexOf(item);
    items.remove(position);
    notifyItemRemoved(position);
}

Using this way will be more efficient than using the mAdapter.notifyDataSetChanged() for change check across your list.

Behold in the documentation all methods in the case of RecycleView.Adapter.

  • So, after updating the database, I would call the methods remove() and `add(), in this order. As for remove, no problem, but add()... if I understood the code above, how will he know how to match each attribute of Rundata, with the corresponding view? Whereas I’m still not using Binding data.

  • @Renefreak If you update the entire bank, or check in any situation if there is any change, you can use the mAdapter.notifyDataSetChanged(). Now for example, you have to add an item that came from the bank, you must use the add() and likewise the remove().

  • I sent the previous comment before I finished and you replied while I edited it. You’re really quick on the trigger :-)

  • @Renefreak notice that at some point you are adding and removing items in your list right?! So try to make these two ways.

  • @Renefreak as you said that each card has a button, you should only update the card. That’s the cool of Recyclerview;

  • how to update the cardView I already have the position, instead of using the methods you presented, I used the methods add() and remove() of the adapter itself. But the important thing is that it worked.

  • @Cool renefreak. If you want to change the answer and put some important consideration, feel free.

Show 2 more comments

1

Its structure is confused, it would be interesting to have the Recyclerview Adapter to complement the answer, but the idea is more or less like this:

In your Recyclerview Adapter you pass a list of elements that make up the cards, correct? Well, to update Recyclerview, all you need is:

  1. Get the data you are collecting in Dialog (from what I saw you already do this)
  2. Instantiate the class you use as a List element with this new data
  3. Swap at the position that was clicked, the old element with the new
  4. Tell your recyclerView that the list has changed through recyclerView.notifyDataSetChanged()
  5. Ready!

Without its code it is difficult to give a more precise answer, but this is the step by step to update it, I took into consideration that Voce makes the Adapter as a documentation suggests, but if you’re using it differently, edit your answer with the Adapter code that I try to be more explicit about.

I think it’s clear but just in case, good luck :P

  • updated the question with the RecyclerView.Adapter. Let me know if you need any more information. I appreciate your cooperation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.