android - RecyclerView 在 notifyDataSetChanged() 上闪烁;

标签 android android-recyclerview notifydatasetchanged

bounty 7 天后到期。这个问题的答案有资格获得 +50 声望奖励。
Vasant Raval正在寻找规范的答案。







在版主删除此问题重复之前,请阅读以下内容
好的,我尝试了不同的答案,但没有任何效果对我有用,例如我禁用了不起作用的动画,我正在尝试使用 this但我没有使用 getItemID 所以我不知道如何处理它
这是我的代码
首页_Fragment.java //好的,我只给出了我认为需要的部分代码,但如果您想查看整个代码,请告诉我我会更新它

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
postRecyclerView.setItemAnimator(null);
        getData();
  return view;
    }
 private void getData() {
        databaseReference.addValueEventListener(new ValueEventListener() {
            @SuppressLint("NotifyDataSetChanged")
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {
                    shimmerFrameLayout.stopShimmer();
                    shimmerFrameLayout.setVisibility(View.GONE);
                    postRecyclerView.setVisibility(View.VISIBLE);
                    mUploads.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        Upload upload = dataSnapshot.getValue(Upload.class);
                        assert upload != null;
                        upload.setmKey(dataSnapshot.getKey());
                        mUploads.add(upload);


                    }

                }
                postsAdapter.setUploads(mUploads);

                //notify the adapter
                postsAdapter.notifyDataSetChanged();
                loading = true;
            }


            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                loading = true;
            }
        });
    }
PostAdapter_Home.java
public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
    public static List<Upload> mUploads;
    public Context mcontext;

    public PostAdapter_Home(Context context, List<Upload> uploads) {
        mUploads = uploads;
        mcontext = context;
    }


    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(mcontext).inflate(R.layout.ex_home, parent, false);
        return new PostViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
                .setBaseColor(Color.parseColor("#F3F3F3"))
                .setBaseAlpha(1)
                .setHighlightColor(Color.parseColor("#E7E7E7"))
                .setHighlightAlpha(1)
                .setDropoff(50)
                .build();
        ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
        shimmerDrawable.setShimmer(shimmer);
        Upload uploadCurrent = mUploads.get(position);
        Glide.with(mcontext)
                .load(uploadCurrent.getmImageUrl())
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .placeholder(shimmerDrawable)
                .centerCrop()
                .fitCenter()
                .into(holder.imageView);

//        holder.imageView.setOnClickListener(view -> changeScaleType(holder, position));

    }


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

    public void setUploads(List<Upload> uploads){
        mUploads=uploads;
    }
    public static class PostViewHolder extends RecyclerView.ViewHolder {

        private final ShapeableImageView imageView;

        public PostViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imagePostHome);

        }


    }
}
上传.java
package com.example.myappnotfinal.AdaptersAndMore;

import com.google.firebase.database.Exclude;

public class Upload {
    private String mImageUrl;
    private String mKey;
    private String mUserName;
    private String mComment;

    public Upload() {

    }

    public Upload(String imageUrl) {
        mImageUrl = imageUrl;
    }

    public String getmUserName() {
        return mUserName;
    }

    public void setmUserName(String mUserName) {
        this.mUserName = mUserName;
    }

    public String getmComment() {
        return mComment;
    }

    public void setmComment(String mComment) {
        this.mComment = mComment;
    }

    public String getmImageUrl() {
        return mImageUrl;
    }

    public void setmImageUrl(String mImageUrl) {
        this.mImageUrl = mImageUrl;
    }

    @Exclude
    public String getmKey() {
        return mKey;
    }

    @Exclude
    public void setmKey(String Key) {
        this.mKey = Key;
    }
}

最佳答案

试试 ListAdapter,它会为你管理所有这些动画。为了实现这一点,我们需要编写一些样板类。
首先,让我们创建适配器。

public class YourAdapter extends ListAdapter<YourModelClass, YourAdapter.YourViewHolder> {

    public YourAdapter(@NonNull DiffUtil.ItemCallback<YourModelClass> diffCallback) {
        super(diffCallback);
    }

    public static class YourViewHolder extends RecyclerView.ViewHolder {
        
        private TextView textViewId;
        private TextView textViewName;

        private YourViewHolder(View view) {
            super(view);
            textViewId = view.findViewById(R.id.textViewId);
            textViewName = view.findViewById(R.id.textViewName);
        }

        static YourViewHolder create(ViewGroup parent) {
            return new YourViewHolder(
                    LayoutInflater.from(parent.getContext())
                            .inflate(
                                    R.layout.your_layout,
                                    parent,
                                    false
                            )
            );
        }

        void bind(YourModelClass model) {
            textViewId.setText(String.valueOf(model.getId()));
            textViewName.setText(model.getName());
        }

    }

    @NonNull
    @Override
    public YourViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return YourViewHolder.create(parent);
    }

    @Override
    public void onBindViewHolder(@NonNull YourViewHolder holder, int position) {
        holder.bind(getItem(position));
    }
}
现在,让我们创建您的类,用 DiffUtill 算法比较列表项。在 areItemsTheSame 中,您需要使用唯一键来比较项目。在 areContentsTheSame 中,我们只是比较两个实例。
public class YourItemCallback extends DiffUtil.ItemCallback<YourModelClass> {

    @Override
    public boolean areItemsTheSame(@NonNull YourModelClass oldItem, @NonNull YourModelClass newItem) {
        return oldItem.getId() == newItem.getId();
    }

    @Override
    public boolean areContentsTheSame(@NonNull YourModelClass oldItem, @NonNull YourModelClass newItem) {
        return Objects.equals(oldItem, newItem);
    }
}
最后,让我们向适配器发送数据。请注意, submitList 方法接收您在适配器中指定的类型列表ListAdapter<YourModelClass, YourAdapter.YourViewHolder>
List<YourModelClass> yourList = Arrays.asList(
                new YourModelClass(1, "John"),
                new YourModelClass(1, "Mac"),
                new YourModelClass(1, "Gu"),
                new YourModelClass(1, "Gabriel")
        );

RecyclerView recyclerView = findViewById(R.id.recyclerView);
YourAdapter yourAdapter = new YourAdapter(new YourItemCallback());
recyclerView.setAdapter(yourAdapter);
yourAdapter.submitList(yourList);

关于android - RecyclerView 在 notifyDataSetChanged() 上闪烁;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69726142/

相关文章:

Android 谷歌地图 CameraUpdateFactory 未初始化

android - 以编程方式将 imageview 的高度设置为 matchparent

java - 如何在TeeChart中用DASH风格绘制ColorLine?

java - 使用 TextInputEditText 在 RecyclerView 中遇到问题

android - 支持库从 23.1.1 更新到 23.2.1 后,RecyclerView 适配器中的 notifyDataSetChange() 变慢

android - RenderThread 与 UI 线程

android - 如何从特定索引开始ArrayList?

android - 如何在不跳过布局的情况下为内部 RecyclerView 项目设置适配器?

java - 通知 RecyclerView 中 Firestore 数据的更改

android - 数据更改后未调用 ExpandableListView getChildrenCount,导致 IndexOutOfBoundsException