簡體   English   中英

刪除/移除列表中的評論后,ArrayList 中的評論會變得混亂

[英]Comments in ArrayList get messed up after deletion / removal of comment in list

我的應用程序中有一個評論功能,用戶可以在其中評論彼此的帖子,也可以喜歡或不喜歡彼此的評論。 此外,如果他們對他們的評論不滿意,他們可以刪除它。 一切正常,直到我刪除評論部分,因為然后我調用notifyDataSetChanged(); notifyItemRangeChanged(); 一切都變得一團糟,因為當評論列表刷新並且我嘗試喜歡列表中的某些評論時,有時會不止一個被喜歡,或者如果我單擊“不喜歡”,有時會不止一個被不喜歡,有時既喜歡又不喜歡最終被選中。

在此處輸入圖片說明

我已經嘗試了一千種方法來修復它,但沒有任何效果。 下面我將向你們展示一些我嘗試過的事情的例子......在 onChildRemoved(); 我試過這樣:

評論活動

private void readComments() {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments").child(mPostId);
        ChildEventListener childEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Comment comment = dataSnapshot.getValue(Comment.class);
                comment.setComment(comment.getComment());
                mCommentList.add(comment);
                keysList.add(dataSnapshot.getKey());
                mCommentAdapter.notifyItemInserted(mCommentList.size() - 1);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                mCommentAdapter.removeComment(dataSnapshot.getKey());
                mRecyclerView.setAdapter(mCommentAdapter);
                mCommentAdapter.notifyDataSetChanged();
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

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

            }
        };

        reference.addChildEventListener(childEventListener);
    }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                int index = keysList.indexOf(dataSnapshot.getKey());
                mCommentList.remove(index);
                mCommentAdapter.notifyItemChanged(index);
                keysList.remove(index);
                mCommentAdapter.notifyItemRangeChanged(index, mCommentList.size());
            }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
            index = keysList.indexOf(dataSnapshot.getKey());
            keysList.remove(index);
            mCommentList.remove(index);
            mCommentAdapter.notifyDataSetChanged();
        }

名單還在繼續。 我已經嘗試了很多這些變體,但在刪除評論后仍然如此,當我嘗試喜歡或不喜歡列表中的評論時,不止一個人喜歡或不喜歡,有時喜歡和不喜歡最終都會被選中。

關於可能導致這種情況的想法?

CommentAdapter (我喜歡和不喜歡評論的方式)

public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.ViewHolder> {

    private Context mContext;
    private List<Comment> mCommentList;

    private String mPostId;
    private String mNotificationId;

    private FirebaseUser mFirebaseUser;

    public CommentAdapter(Context mContext, List<Comment> mComment, String mPostId) {
        this.mContext = mContext;
        this.mCommentList = mComment;
        this.mPostId = mPostId;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.comment_item, parent, false);

        return new CommentAdapter.ViewHolder(view);
    }

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

        mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        final Comment comment = mCommentList.get(position);

        holder.comment.setText(comment.getComment());

        commentLike(comment.getCommentid(), holder.commentLike);
        commentDislike(comment.getCommentid(), holder.commentDislike);
        getUserInfo(holder.image_profile, holder.username, comment.getPublisher());
        commentLikesNumber(holder.commentLikesNumber, comment.getCommentid());
        commentDislikesNumber(holder.commentDislikesNumber, comment.getCommentid());
        commentResponseNumber(holder.commentResponseNumber, comment.getCommentid());

        holder.iconComment.setOnClickListener(v -> {
            Intent intent = new Intent(mContext, ResponseActivity.class);
            intent.putExtra("commentid", comment.getCommentid());
            intent.putExtra("publisherid", comment.getPublisher());
            intent.putExtra("postid", mPostId);
            mContext.startActivity(intent);
        });

        holder.commentLike.setOnClickListener(v -> {
            if (holder.commentLike.getTag().equals("like") && holder.commentDislike.getTag().equals("dislike")) {
                likeComment(comment.getCommentid(), mPostId, comment.getPublisher());
            } else if (holder.commentLike.getTag().equals("like") && holder.commentDislike.getTag().equals("disliked")) {
                likeComment(comment.getCommentid(), mPostId, comment.getPublisher());
                removeDislike(comment.getCommentid());
            } else {
                removeLike(comment.getPublisher(), comment.getCommentid());
            }
        });

        holder.commentDislike.setOnClickListener(v -> {
            if (holder.commentDislike.getTag().equals("dislike") && holder.commentLike.getTag().equals("like")) {
                dislikeComment(comment.getCommentid());
                Toast.makeText(mContext, "Don't be mean", Toast.LENGTH_SHORT).show();
            } else if (holder.commentDislike.getTag().equals("dislike") && holder.commentLike.getTag().equals("liked")) {
                dislikeComment(comment.getCommentid());
                removeLike(comment.getPublisher(), comment.getCommentid());
                Toast.makeText(mContext, "Don't be mean", Toast.LENGTH_SHORT).show();
            } else {
                removeDislike(comment.getCommentid());
            }
        });

        holder.image_profile.setOnClickListener(v -> {
            Intent intent = new Intent(mContext, MainActivity.class);
            intent.putExtra("publisherid", comment.getPublisher());
            mContext.startActivity(intent);
        });

        //Timestamp to Date
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        Date date = new Date(timestamp.getTime());

        //Current timestamp
        Calendar calendar = Calendar.getInstance();
        long ts = calendar.getTimeInMillis();

        //Getting comment timestamp from database
        long timestampOfComment = comment.getTimestamp();

        //SECOND WAY

        long duration = ts - timestampOfComment;

        long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
        long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
        long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
        long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);

        if (diffInSeconds < 10) {
            holder.timestamp.setText(" \u25CF " + "Just now");
        } else if (diffInSeconds > 10 && diffInSeconds < 60) {
            holder.timestamp.setText(" \u25CF " + diffInSeconds + " seconds ago");
        } else if (diffInSeconds > 60 && diffInMinutes == 1) {
            holder.timestamp.setText(" \u25CF " + diffInMinutes + " minute ago");
        } else if (diffInSeconds > 60 && diffInMinutes < 60) {
            holder.timestamp.setText(" \u25CF " + diffInMinutes + " minutes ago");
        } else if (diffInSeconds > 60 && diffInMinutes > 60 && diffInHours == 1) {
            holder.timestamp.setText(" \u25CF " + diffInHours + " hour ago");
        } else if (diffInSeconds > 60 && diffInMinutes > 60 && diffInHours > 1 && diffInHours < 24) {
            holder.timestamp.setText(" \u25CF " + diffInHours + " hours ago");
        } else if (diffInSeconds > 60 && diffInMinutes > 60 && diffInHours > 24 && diffInDays == 1) {
            holder.timestamp.setText(" \u25CF " + diffInDays + " day ago");
        } else if (diffInSeconds > 60 && diffInMinutes > 60 && diffInHours > 24 && diffInDays > 1) {
            holder.timestamp.setText(" \u25CF " + diffInDays + " days ago");
        }

        holder.itemView.setOnLongClickListener(v -> {
            if (comment.getPublisher().equals(mFirebaseUser.getUid())) {
                AlertDialog alertDialog = new AlertDialog.Builder(mContext).create();
                alertDialog.setTitle("Would you like to delete this comment?");
                alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "No", (dialog, which) -> dialog.dismiss());
                alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", (dialog, which) -> {
                    deleteCommentNotification(mPostId, comment.getCommentid());
                    FirebaseDatabase.getInstance().getReference("Comments Liked").child(comment.getCommentid()).setValue(null);
                    FirebaseDatabase.getInstance().getReference("Comments Disliked").child(comment.getCommentid()).setValue(null);
                    FirebaseDatabase.getInstance().getReference("Responses").child(comment.getCommentid()).setValue(null);
                    Toast.makeText(mContext, "Your comment has been deleted.", Toast.LENGTH_SHORT).show();
                    dialog.dismiss();
                });
                alertDialog.show();
            }
            return true;
        });
    }

    @Override
    public int getItemCount() {
        if (mCommentList != null) {
            return mCommentList.size();
        } else {
            return 0;
        }
    }

    static class ViewHolder extends RecyclerView.ViewHolder {

        CircleImageView image_profile;
        TextView username, comment, commentLikesNumber, commentDislikesNumber, commentResponseNumber, timestamp;
        ImageView commentLike, commentDislike, iconComment;

        ViewHolder(@NonNull View itemView) {
            super(itemView);

            image_profile = itemView.findViewById(R.id.image_profile);
            comment = itemView.findViewById(R.id.comment);
            username = itemView.findViewById(R.id.username);
            commentLike = itemView.findViewById(R.id.icon_thumb_up_grey);
            commentDislike = itemView.findViewById(R.id.icon_thumb_down_grey);
            commentLikesNumber = itemView.findViewById(R.id.comment_likes_number);
            commentDislikesNumber = itemView.findViewById(R.id.comment_dislikes_number);
            iconComment = itemView.findViewById(R.id.icon_comment_grey);
            commentResponseNumber = itemView.findViewById(R.id.comment_response_number);
            timestamp = itemView.findViewById(R.id.timestamp);
        }
    }

    private void deleteCommentNotification(String postid, String commentid) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments").child(postid).child(commentid);
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    String notificationId = dataSnapshot.child("notificationId").getValue(String.class);
                    String user = dataSnapshot.child("for").getValue(String.class);
                    if (notificationId != null && user != null) {
                        FirebaseDatabase.getInstance().getReference("Notifications").child(user).child(notificationId).removeValue();
                        reference.removeValue();
                    }
                }
            }

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

            }
        });
    }

    private void getUserInfo(final ImageView prof_image, final TextView username, String publisherid) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Users").child(publisherid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                User user = dataSnapshot.getValue(User.class);
                if (user != null) {
                    Glide.with(mContext.getApplicationContext()).load(user.getImageurl()).into(prof_image);
                    username.setText(user.getUsername());
                } else {
                    prof_image.setImageResource(R.drawable.profile_placeholder);
                    username.setVisibility(View.GONE);
                }
            }

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

            }
        });
    }

    public void removeComment(final String key) {
        for (int i = 0; i < mCommentList.size(); i++) {
            if (mCommentList.get(i).getCommentid().equals(key)) {
                mCommentList.remove(i);
                break;
            }
        }
    }

    private void commentLike(final String commentid, final ImageView imageView) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Liked").child(commentid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (mFirebaseUser != null)
                    if (dataSnapshot.child(mFirebaseUser.getUid()).exists()) {
                        imageView.setImageResource(R.drawable.ic_thumb_up_blue);
                        imageView.setTag("liked");
                    } else {
                        imageView.setImageResource(R.drawable.ic_thumb_up_grey);
                        imageView.setTag("like");
                    }
            }

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

            }
        });
    }

    private void commentDislike(final String commentid, final ImageView imageView) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Disliked").child(commentid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (mFirebaseUser != null)
                    if (dataSnapshot.child(mFirebaseUser.getUid()).exists()) {
                        imageView.setImageResource(R.drawable.ic_thumb_down_blue);
                        imageView.setTag("disliked");
                    } else {
                        imageView.setImageResource(R.drawable.ic_thumb_down_grey);
                        imageView.setTag("dislike");
                    }
            }

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

            }
        });
    }

    private void commentLikesNumber(TextView commentLikesNumber, String commentid) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Liked").child(commentid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                long commentLikes = dataSnapshot.getChildrenCount();
                if (commentLikes == 0) {
                    commentLikesNumber.setVisibility(View.INVISIBLE);
                } else {
                    commentLikesNumber.setVisibility(View.VISIBLE);
                    commentLikesNumber.setText(String.valueOf(commentLikes));
                }
            }

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

            }
        });
    }

    private void commentDislikesNumber(TextView commentDislikesNumber, String commentid) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Disliked").child(commentid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                long commentDislikes = dataSnapshot.getChildrenCount();
                if (commentDislikes == 0) {
                    commentDislikesNumber.setVisibility(View.INVISIBLE);
                } else {
                    commentDislikesNumber.setVisibility(View.VISIBLE);
                    commentDislikesNumber.setText(String.valueOf(commentDislikes));
                }
            }

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

            }
        });
    }

    private void commentResponseNumber(TextView commentResponseNumber, String commentid) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Responses").child(commentid);
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                long commentResponses = dataSnapshot.getChildrenCount();
                if (commentResponses == 0) {
                    commentResponseNumber.setVisibility(View.INVISIBLE);
                } else {
                    commentResponseNumber.setVisibility(View.VISIBLE);
                    commentResponseNumber.setText(String.valueOf(commentResponses));
                }
            }

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

            }
        });
    }

    private void likeComment(String commentId, String postId, String userId) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Liked").child(commentId).child(mFirebaseUser.getUid());

        mNotificationId = reference.push().getKey();

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("notificationId", mNotificationId);
        hashMap.put("commentid", commentId);
        hashMap.put("userid", mFirebaseUser.getUid());

        reference.setValue(hashMap);

        HashMap<String, Object> hashMap1 = new HashMap<>();
        hashMap1.put("userid", mFirebaseUser.getUid());
        hashMap1.put("comment", "liked your comment");
        hashMap1.put("postid", postId);
        hashMap1.put("ispost", true);
        hashMap1.put("notificationId", mNotificationId);
        hashMap1.put("commentid", commentId);
        hashMap1.put("seen", false);
        hashMap1.put("type", "");

        if (!mFirebaseUser.getUid().equals(userId)) {
            FirebaseDatabase.getInstance().getReference("Notifications").child(userId).child(mNotificationId).setValue(hashMap1);
        }
    }

    private void removeLike(String userId, String commentId) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments Liked").child(commentId).child(mFirebaseUser.getUid());
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    String notificationId = dataSnapshot.child("notificationId").getValue(String.class);
                    if (notificationId != null) {
                        FirebaseDatabase.getInstance().getReference("Notifications").child(userId).child(notificationId).removeValue();
                        reference.removeValue();
                    }
                }
            }

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

            }
        });
    }

    private void dislikeComment(String commentId) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments Disliked").child(commentId).child(mFirebaseUser.getUid());

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("commentid", commentId);
        hashMap.put("notificationId", mNotificationId);
        hashMap.put("userid", mFirebaseUser.getUid());

        reference.setValue(hashMap);
    }

    private void removeDislike(String commentId) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments Disliked").child(commentId).child(mFirebaseUser.getUid());
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                reference.removeValue();
            }

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

            }
        });
    }
}

奇怪行為的原因是您在每次調用onBindViewHolder注冊的ValueEventListener對象。 每次新項目滾動到視圖中或更改其數據時,都會調用onBindViewHolder方法。 由於您永遠不會取消注冊偵聽器,因此它們會繼續更新視圖,即使它們可能已經綁定到其他項目。

不要在onBindViewHolder注冊任何監聽onBindViewHolder 使用您的適配器設置ValueEventListener並在不再使用適配器時取消注冊它們。 在偵聽器中調用適配器的通知方法而不是直接更新視圖。 將 OnClickListeners 的注冊移動到您的 ViewHolder 中並使它們通用,這樣它們就不會綁定到特定項目。 onBindViewHolder應該簡單地更新您的視圖。

所有更改都應該可以解決您的問題並使滾動更加流暢;-)

注釋適配器

public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.ViewHolder> {

private Context mContext;
private List<Comment> mCommentList;

private String mPostId;
private String mNotificationId;

private FirebaseUser mFirebaseUser;

public CommentAdapter(Context mContext, List<Item> items, String mPostId) {
  this.items = items;
  this.mPostId = mPostId;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  View view = LayoutInflater.from(mContext).inflate(R.layout.comment_item, parent, false);
  return new CommentAdapter.ViewHolder(mContext, mPostId, view);
}

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

  holder.update(items.get(position));
  
}

視圖持有人

public static class ViewHolder extends RecyclerView.ViewHolder {

private Item item;

public ViewHolder(Context context, String mPostId, View itemView) {  
        super(itemView);  
        
        // ...
    
        // Register OnClickListeners here once for the view. Example:
        icon.setOnClickListener(v -> {
        
          if (item != null) {
              Comment comment = item.getComment();
              Intent intent = new Intent(mContext, ResponseActivity.class);
              intent.putExtra("commentid", comment.getCommentid());
              intent.putExtra("publisherid", comment.getPublisher());
              intent.putExtra("postid", mPostId);
              mContext.startActivity(intent);
          }
        });
        
       // ...
    }

public void update(Item item) {
    this.item = item;
    update(item.getComment());
    update(item.getLikeStatus());
}

public void update(Comment comment) {
    textControl.setText(comment.getText());
    // ...
}

public void update(LikeStatus status) {
    
    if (status.likes == 0) {
      likeNumbersText.setVisibility(View.INVISIBLE);
    } else {
      likeNumbersText.setVisibility(View.VISIBLE);
      likeNumbersText.setText(String.valueOf(likes));
    }
    
    if (status.dislikes == 0) {
      dislikeNumbersText.setVisibility(View.INVISIBLE);
    } else {
      dislikeNumbersText.setVisibility(View.VISIBLE);
      dislikesNumbersText.setText(String.valueOf(likes));
    }
  }
    // ...
}

活動

  DatabaseReference comments = FirebaseDatabase.getInstance().getReference("Comments").child(mPostId);
ChildEventListener childEventListener = new ChildEventListener() {
   
    @Override
    public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
        Comment comment = dataSnapshot.getValue(Comment.class);
        Item item = getItemByCommentId(dataSnapshot.getKey());
        item.setComment(comment);
        
        mCommentAdatper.notifyItemChanged(comment.getPosition()); 
    }

    //...
  
};

comments.addChildEventListener(childEventListener);


DatabaseReference likes = FirebaseDatabase.getInstance().getReference("Comments Liked");
ChildEventListener childEventListener = new ChildEventListener() {
   
    @Override
    public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
        long likes = dataSnapshot.getChildrenCount();
        String commendId = dataSnapshot.getKey();
        Item item = getItemByCommentId(commendId);
        Comment comment = item.getComment();
        LikeStatus likeStatus = item.getLikeStatus();
        likeStatus.likes = likes;
      
        mCommentAdatper.notifyItemChanged(comment.getPosition());  
    }
    
    // ...
  
};

likes.addChildEventListener(childEventListener);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM