Recycler view not updating item after editing it

37 Views Asked by At

On my Android application I have a RecyclerView with a list of objects from a class called Apiario. In each item of the list I give the option to remove that item or to edit one of its variables. I also have an option to add a new item to the list. When the user chooses to edit an item a new activity starts with a form so he can enter the new values.

When I delete an item everything works as expected and the item is indeed deleted from the ArrayList.

When I add an item everything also works as expected.

The problem is when I try to update an item. Although in the form activity the object is correctly updated, once I go back to the View with the RecyclerView the changes aren't there.

RecyclerView Activity

public class AnualDeclarationActivity extends AppCompatActivity implements ApiarioAdapter.ApiarioClickListener {

    private ApiarioAdapter apiarioAdapter;

    private ArrayList<Apiario> apiList;
    private static final int EDIT_APIARIO_REQUEST_CODE = 1;
    private static final int ADD_APIARIO_REQUEST_CODE = 2;

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

        RecyclerView recyclerView = findViewById(R.id.recyclerViewApiarios);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        this.apiList = new ArrayList<>();

        DatabaseReference mDatabaseQuery = 
        FirebaseDatabase.getInstance().getReference("apiario");

        Query query = mDatabaseQuery.orderByChild("estado").equalTo("Aceite");

        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for(DataSnapshot dataSnapshot : snapshot.getChildren()){

                    Apiario apiario = dataSnapshot.getValue(Apiario.class);
                    apiList.add(apiario);
                }

                apiarioAdapter = new ApiarioAdapter(apiList, AnualDeclarationActivity.this);
                recyclerView.setAdapter(apiarioAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

        ImageButton btnAddApiario = findViewById(R.id.btnAddApiario);
        btnAddApiario.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(AnualDeclarationActivity.this, AddApiarioActivity.class);
                startActivityForResult(intent, ADD_APIARIO_REQUEST_CODE);
            }
        });
    }

    @Override
    public void onEditClick(Apiario apiario) {
        Intent intent = new Intent(this, EditApiarioActivity.class);
        intent.putExtra("apiario", apiario);
        startActivityForResult(intent, EDIT_APIARIO_REQUEST_CODE);
    }

    @Override
    public void onDeleteClick(Apiario apiario) {
        showDeleteConfirmationDialog(apiario);
    }

    private void showDeleteConfirmationDialog(final Apiario apiario) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Delete Apiario");
        builder.setMessage("Are you sure you want to delete this Apiario?");

        builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                deleteApiario(apiario);
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        });

        builder.create().show();
    }

    private void deleteApiario(Apiario apiario) {
        apiList.remove(apiario);
        apiarioAdapter.notifyDataSetChanged();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ADD_APIARIO_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Apiario newApiario = data.getParcelableExtra("newApiario");
            apiList.add(newApiario);
            apiarioAdapter.notifyDataSetChanged();
        }

        if (requestCode == EDIT_APIARIO_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Apiario modifiedApiario = data.getParcelableExtra("modifiedApiario");
            int position = findPositionOfApiarioInList(modifiedApiario);
            if (position != -1) {
                apiList.set(position, modifiedApiario);
                apiarioAdapter.notifyItemChanged(position);
            }
        }
    }

    private int findPositionOfApiarioInList(Apiario apiario) {
        for (int i = 0; i < apiList.size(); i++) {
            if (apiList.get(i).getNomeApiario().equals(apiario.getNomeApiario())) {
                return i;
            }
        }
        return -1;
    }
}

Adapter

public class ApiarioAdapter extends RecyclerView.Adapter<ApiarioAdapter.ApiarioViewHolder> {

    private List<Apiario> apiarios;
    private ApiarioClickListener listener;

    public interface ApiarioClickListener {
        void onEditClick(Apiario apiario);
        void onDeleteClick(Apiario apiario);
    }

    public ApiarioAdapter(List<Apiario> apiarios, ApiarioClickListener listener) {
        this.apiarios = apiarios;
        this.listener = listener;
    }

    public class ApiarioViewHolder extends RecyclerView.ViewHolder {
        TextView textName;
        TextView textColmeias;

        Button btnEdit;
        Button btnDelete;

        public ApiarioViewHolder(@NonNull View itemView) {
            super(itemView);
            textName = itemView.findViewById(R.id.textName);
            textColmeias =itemView.findViewById(R.id.textColmeias);


            btnEdit = itemView.findViewById(R.id.btnEdit);
            btnDelete = itemView.findViewById(R.id.btnDelete);
        }
    }

    @NonNull
    @Override
    public ApiarioViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.apiario_item, parent, false);
        return new ApiarioViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ApiarioViewHolder holder, int position) {
        final Apiario apiario = apiarios.get(position);

        holder.textName.setText("Nome: " + apiario.getNomeApiario());
        holder.textColmeias.setText("Colmeias: " + apiario.getNumColmeias());

        holder.btnEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Apiario selectedApiario = apiarios.get(holder.getAdapterPosition());
                openEditApiarioActivity(view.getContext(), selectedApiario);
            }
        });

        holder.btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listener.onDeleteClick(apiario);
            }
        });
    }

    private void openEditApiarioActivity(Context context, Apiario apiario) {
        Intent intent = new Intent(context, EditApiarioActivity.class);
        intent.putExtra("apiario", apiario);
        context.startActivity(intent);
    }

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

Edit Apiario Activity

public class EditApiarioActivity extends AppCompatActivity {

    private EditText editTextNumColmeias;
    private Button btnSubmit;

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

        editTextNumColmeias = findViewById(R.id.edtNumColmeias);
        btnSubmit = findViewById(R.id.btnSubmit);

        Apiario apiario = getIntent().getParcelableExtra("apiario");

        if (apiario != null) {
            editTextNumColmeias.setText(String.valueOf(apiario.getNumColmeias()));
        }

        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int modifiedNumColmeias = Integer.parseInt(editTextNumColmeias.getText().toString());

                if (apiario != null) {
                    apiario.setNumColmeias(modifiedNumColmeias);
                    Intent resultIntent = new Intent();
                    resultIntent.putExtra("modifiedApiario", apiario);
                    setResult(RESULT_OK, resultIntent);
                    finish();
                }
            }
        });
    }
}

I tried to place logs across the code and this is what I found:

  • After I click the submit button on the EditApiarioActivity, the method onActivityResult is not called.
  • The selected Apiario is correctly passed to EditApiarioActivity
  • EditApiarioActivity correctly updates the object but when the application goes back to the RecyclerViewActivity the changes are not reflected

What am I doing wrong? I can't find the problem.

1

There are 1 best solutions below

2
ninhnau19 On

Problem is in your Adapter class.

holder.btnEdit.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
          Apiario selectedApiario = apiarios.get(holder.getAdapterPosition());
          openEditApiarioActivity(view.getContext(), selectedApiario);
      }
});

you forgot called listener

listener.onEditClick(apiario);

It should be:

holder.btnEdit.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
          Apiario selectedApiario = apiarios.get(holder.getAdapterPosition());
          listener.onEditClick(selectedApiario);
      }
});

so when you click edit, it will run this block:

    private void openEditApiarioActivity(Context context, Apiario apiario) {
        Intent intent = new Intent(context, EditApiarioActivity.class);
        intent.putExtra("apiario", apiario);
        context.startActivity(intent);
    }

and you see, it's just startActivity, not startActivityForResult