Home > Net >  Android recyclerview shows more values after data change
Android recyclerview shows more values after data change

Time:10-04

I am trying to edit an item in a recyclerview which shows some data from Firebase. But after editing the data set is not changed. It shows previous as well as the new updated items, until the activity is reloaded. The screenshots are given at the end.

I am editing the items via an alertdialog. Following is the code:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.MyViewHolder> {
    ArrayList<User_Post> user_posts=null;
Context context;
public ListAdapter(@Nullable ArrayList<User_Post> posts, Context c) {
        this.user_posts=posts;      // the data set
        this.context=c;
    }

Upon item's edit button click the alertdialog opens:

  //'post' is an instance of type User_Post containing the current data item.

dialogBuilder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(isValid()) {
                        post.setWorkType(txtType.getSelectedItem().toString());
                        post.setWorkDescription(txtDetails.getText().toString());
    
                        user_posts.set(position,post);
                        updateDataSet(user_posts);
    
                        saveToFirebase(post,"edit");
                        Toast.makeText(context, "Post updated", Toast.LENGTH_SHORT).show();
    
                    }
                }

Code for updating firebase data:

private void saveToFirebase(User_Post post, String task) {
    String id=post.getPostID();

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageRef = storage.getReferenceFromUrl("gs://smart-worker-c73c4.appspot.com/gs:");
    DatabaseReference myRef = database.getReference("posts");

    if(task.equals("edit")) {
        myRef.child(id).setValue(post);
    }
    else {
        myRef.child(id).setValue(null);
        storageRef.child(id).delete();
    }
}

For updating data set:

 private void updateDataSet(ArrayList<User_Post> posts){
        this.user_posts=posts;
        notifyDataSetChanged();

    }

Screenshot before editting... enter image description here

Screenshot after editting... enter image description here

Thanks for your time and concideration!

CodePudding user response:

i think the problem is the position you give to the list maybe its not a right position, you didn't mention that where do you get it from and when you update it.

CodePudding user response:

It shows previous as well as the new updated items, until the activity is reloaded

So, when you reload the activity, the data is show, therefore the data is saved successfully into firebase, and grabbed in reloading the activity. So, this issue is not related to firebase.

Also you decided to not having a persistent event listener to firebase, and instead you updated the RecyclerView locally. with:

 private void updateDataSet(ArrayList<User_Post> posts){
        this.user_posts = posts;
        notifyDataSetChanged();
}

Although I'd suggest to clear, and then rebuild the list before notifying the change:

 private void updateDataSet(ArrayList<User_Post> posts){
        this.user_posts.clear();
        this.user_posts.addAll(posts);        
        notifyDataSetChanged();
}

This is not the optimum procedure, because calling notifyDataSetChanged() is expensive; instead I'd recommend to notifyItemInserted() or notifyItemRangeChanged(); to deploy only the changes to the RecyclerView.

For instance if you just will pass a single item:

 private void updateDataSet(User_Post post){
        this.user_posts.add(post);        
        notifyItemInserted(this.user_posts.size()-1);
}

And for a range of items:

 private void updateDataSet(ArrayList<User_Post> posts){ // Pass only those items that are changed
        int currentSize = this.user_posts.size();
        this.user_posts.addAll(posts);   
        int newSize = this.user_posts.size();     
        notifyItemInserted(currentSize, newSize - 1);
}
  • Related