Recyclerview从适配器删除项目后获取现有数据,并且无法正确更新

问题描述 投票:0回答:2

我尝试使用带有Firebase数据库的自定义适配器在片段中实现朋友请求功能。问题是,当用户接受或删除某人的请求时,它会从Firebase中删除,但无法在RecyclerView中正确更新。此问题仅在运行时发生。如果刷新页面,那么我的问题就消失了。

让我有两个朋友的请求。如果删除第二个数据,则第二个数据将从RecyclerView中消失,但问题是RecyclerView显示第一个数据加倍。如果我删除第一个数据,则第一个数据进入第二行,第二个数据进入第一行。

这是我的数据库截图

enter image description here

片段类-

public class NotificationFragment extends Fragment {

private RecyclerView NotificationRecyclerView;
private NotificationAdapter adapter;
private List<Friend> friendList;

public NotificationFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_notification, container, false);

    NotificationRecyclerView = view.findViewById(R.id.NotificationRecyclerView);
    NotificationRecyclerView.setHasFixedSize(true);
    LinearLayoutManager LayoutManager = new LinearLayoutManager(getContext());
    NotificationRecyclerView.setLayoutManager(LayoutManager);
    friendList = new ArrayList<>();
    adapter = new NotificationAdapter(getContext(), friendList);
    NotificationRecyclerView.setAdapter(adapter);

    readAllNotification();

    return view;
}

private void readAllNotification() {

    final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("FriendRequest");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Friend friend = snapshot.getValue(Friend.class);
                if (firebaseUser.getUid().equals(friend.getReceiverID())) {
                    friendList.add(friend);
                }
            }

            Collections.reverse(friendList);
            adapter.notifyDataSetChanged();
        }

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

        }
    });
}

}

自定义适配器-

public class NotificationAdapter extends RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder> {

private Context context;
private List<Friend> friendList;

public NotificationAdapter(Context context, List<Friend> friendList) {
    this.context = context;
    this.friendList = friendList;
}

@NonNull
@Override
public NotificationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(context).inflate(R.layout.single_notification_item, parent, false);
    return new NotificationAdapter.NotificationViewHolder(view);

}

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

    final Friend friend = friendList.get(position);

    getUserInfo(holder.profileImage, holder.NotificationUserName, friend.getSenderID());

    holder.cancelRequestButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FirebaseDatabase.getInstance().getReference("FriendRequest")
                    .child(friend.getRequestID()).removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    removeItem(position);
                    Toast.makeText(context, "removed", Toast.LENGTH_SHORT).show();
                }
            });
        }
    });

}

public void removeItem(int position) {
    friendList.remove(position);
    notifyDataSetChanged();
}

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

private void getUserInfo(final CircleImageView prfileImage, final TextView NotificationUserName, String senderID) {

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(senderID);
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Users users = dataSnapshot.getValue(Users.class);

            NotificationUserName.setText(users.getUserName());
            Picasso.with(context).load(users.getImageUrl()).into(prfileImage);
        }

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

        }
    });
}

public class NotificationViewHolder extends RecyclerView.ViewHolder {

    private TextView NotificationUserName;
    private Button cancelRequestButton;
    private CircleImageView profileImage;

    public NotificationViewHolder(@NonNull View itemView) {
        super(itemView);

        NotificationUserName = itemView.findViewById(R.id.NotificationUserName);
        cancelRequestButton = itemView.findViewById(R.id.cancelRequestBtn);
        profileImage = itemView.findViewById(R.id.profileImage);
    }
}

}

我的APP问题屏幕截图-让我有两个要求1)如果我删除第二个数据,则第一个数据显示为双精度:

enter image description here2)如果我删除第一数据,则第一数据进入第二行,第二数据进入第一行:

enter image description here

android android-studio android-recyclerview recycler-adapter custom-adapter
2个回答
0
投票

替换

 removeItem(position);

with

 removeItem(holder.getAdapterPosition());

0
投票

您不适当地在recyclerView中初始化adapteronCreateView。您必须重写方法onViewCreated,然后初始化recyclerView和适配器。尝试这样

public class NotificationFragment extends Fragment {

private RecyclerView NotificationRecyclerView;
private NotificationAdapter adapter;
private List<Friend> friendList;

public NotificationFragment() {
// Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                     Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_notification, container, false);


return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

  NotificationRecyclerView = view.findViewById(R.id.NotificationRecyclerView);
NotificationRecyclerView.setHasFixedSize(true);
LinearLayoutManager LayoutManager = new LinearLayoutManager(getContext());
NotificationRecyclerView.setLayoutManager(LayoutManager);
friendList = new ArrayList<>();
adapter = new NotificationAdapter(getContext(), friendList);
NotificationRecyclerView.setAdapter(adapter);

readAllNotification();

}

private void readAllNotification() {

final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

DatabaseReference reference = FirebaseDatabase.getInstance().getReference("FriendRequest");
reference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Friend friend = snapshot.getValue(Friend.class);
            if (firebaseUser.getUid().equals(friend.getReceiverID())) {
                friendList.add(friend);
            }
        }

        Collections.reverse(friendList);
        adapter.notifyDataSetChanged();
    }

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

    }
});
}

[好,我刚刚注意到您使用removeItemholder.getAdapterPosition()方法中传递了一个参数,这导致了您的问题。尝试传递public void onBindViewHolder(@NonNull final NotificationViewHolder holder, final int position)提供的位置。因此,基本错误是当您位于[ C0],则无需使用onBindViewHolder,因为holder.getAdapterPosition()已经在给您职位[>

onBindViewHolder方法中,使用removeItem代替notifyDataSetChanged尝试这样

notifyItemRemoved(position)
© www.soinside.com 2019 - 2024. All rights reserved.