How to update the recyclerView after updating data via dialog

1

My application works something like this.

Within 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. 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);
    }
}

}

What now? Who can save us?

    
asked by anonymous 24.01.2017 / 03:24

2 answers

3

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

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, it will be more efficient than using mAdapter.notifyDataSetChanged() for change checking throughout your list.

See in the documentation all methods dealing with RecycleView.Adapter .

    
24.01.2017 / 13:23
1

Its structure is confusing, it would be interesting to have the adapter from RecyclerView to complement the response, but the idea goes something like this:

On your RecyclerView adapter you pass through the builder a list of elements that make up the cards, correct? Well, to update the RecyclerView, all you need is:

  • Take the data you are collecting in Dialog (from what I saw you already do this)
  • Instantiate the class you use as List element with these new data
  • Switch in the position that was clicked, the old element with the new
  • Prompt for your recyclerView that the list has changed, through recyclerView.notifyDataSetChanged()
  • Ready!
  • Without your 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 you make the adapter as documentation suggests, but if you are using it in a different way, edit your answer with the adapter code that I try to be more explicit.

    I think it was clear but for the sake of the no, good luck: P

        
    24.01.2017 / 04:33