查看传呼机,回收者视图如果从其他活动/碎片回来,物品的碎片成倍增加

问题描述

我有主要活动,其中有5个片段由 view pager 2 (不能滑动)和底部导航托管。第一个片段的名称 home片段。主页片段包含

1个查看寻呼机::其中显示了来自Firebase的一些图片(使用寻呼机适配器)

2个回收站视图::其中也显示了一些来自firebase的项目(单击可转到其他活动)

问题::当我浏览带有底部导航的片段时,效果很好。但是当我从第5个片段(最后一个第1个片段(家庭片段)时,有时分页器,回收站视图中的项目会闪烁一倍(好像是重新添加的项目) 。当我去另一项活动并在一段时间后返回时,也会发生同样的事情。

Recycler View适配器

public class Courselistadapter extends RecyclerView.Adapter<Courselistadapter.CourseListViewHolder> {

    public static final int HOME_PAGE = 1;
    public static final int disPLAY_COURSE = 2;

    private Picasso mPicasso;

    private List<displayCourse> courseList;

    private static final String TAG = "Courselistadapter";

    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClick(int position,View view);
    }

    private String mSender;

    public void setonItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    public Courselistadapter(List<displayCourse> courseList,String sender) {
        this.courseList = courseList;
        this.mSender = sender;
        mPicasso = Picasso.get();
    }

    @NonNull
    @Override
    public CourseListViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());

        switch (viewType) {
            case 1:
                View view1 = inflater.inflate(R.layout.recom_course_home_layout,parent,false);
                return new CourseListViewHolder(view1,mListener);
            case 2:
                View view2 = inflater.inflate(R.layout.display_course_layout,false);
                return new CourseListViewHolder(view2,mListener);

            default:
                View view3 = inflater.inflate(R.layout.section_video_item_layout,false);
                return new CourseListViewHolder(view3,mListener);
        }
    }

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

        holder.title.setText(courseList.get(position).getCourseTitle());

        mPicasso.load(courseList.get(position).getThumbnailURL())
                .networkPolicy(NetworkPolicy.OFFLINE)
                .into(holder.thumbnail,new Callback() {
                    @Override
                    public void onSuccess() {

                    }

                    @Override
                    public void onError(Exception e) {
                        mPicasso.load(courseList.get(position).getThumbnailURL())
                                .error(R.drawable.ofklogo)
                                .into(holder.thumbnail,new Callback() {
                                    @Override
                                    public void onSuccess() {

                                    }

                                    @Override
                                    public void onError(Exception e) {

                                    }
                                });
                    }
                });
    }

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

    public static class CourseListViewHolder extends RecyclerView.ViewHolder {

        ImageView thumbnail;
        TextView title;

        public CourseListViewHolder(@NonNull View itemView,final OnItemClickListener listener) {
            super(itemView);

            title = itemView.findViewById(R.id.courseTitle);
            thumbnail = itemView.findViewById(R.id.courseThumbNailImageView);

            itemView.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if (listener != null) {
                        if (position != RecyclerView.NO_POSITION) {
                            listener.onItemClick(position,view);
                        }
                    }
                }
            });
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (mSender.equals("home_page")) {
            return HOME_PAGE;
        } else if (mSender.equals("displayCourse")) {
            return disPLAY_COURSE;
        }
        return -1;
    }
}

在家庭片段onCreateView()中,我正在使用此适配器

mainActivityviewmodel.getRandomCourseLiveData_2().observe(this,new Observer<DataSnapshot>() {
            @Override
            public void onChanged(DataSnapshot dataSnapshot) {
                displayCourse course = dataSnapshot.getValue(displayCourse.class);
                randomCourse_2.add(course);
                recom_course_2 = new Courselistadapter(randomCourse_2,"home_page");
                binding.randomCourseRecyclerView2.setAdapter(recom_course_2);

                recom_course_2.setonItemClickListener(new Courselistadapter.OnItemClickListener() {
                    @Override
                    public void onItemClick(int position,View view) {
                        Intent intent = new Intent(getActivity(),CourseActivity.class);
                        intent.putExtra("section_name","Arts");
                        intent.putExtra("course_name",randomCourse_2.get(position).getCourseTitle());
                        intent.putExtra("course_name_english",randomCourse_2.get(position).getCourseTitleEnglish());
                        intent.putExtra("from","home");
                        startActivity(intent);
                        Log.d(TAG,"onItemClick: " + randomCourse_2.get(position).getCourseTitle());
                        Log.d(TAG,"onItemClick: " + randomCourse_2.get(position).getCourseTitleEnglish());
                    }
                });
            }
        });

解决方法

您创建并填充观察LiveData对象的回收者视图。在某些情况下,LiveData会在重新创建android组件时再次触发旧事件,即使未重新创建视图模型也是如此。对于Google来说,半成品解决方案是一种正常做法,Jetpack库的一半是闪亮的东西。

要解决此问题,您必须使用更好的观察器库(如rxJava)或采取一些变通办法,例如将LiveData有效负载包装在诸如https://github.com/Link184/ArchitectureMVVM/blob/master/library/src/main/java/com/link184/architecture/mvvm/common/Event.kt的对象中,并在此处https://github.com/Link184/ArchitectureMVVM/blob/master/library/src/main/java/com/link184/architecture/mvvm/base/MvvmContext.kt进行观察,

myLiveData.postValue(Event(MyPaload()))

myLiveData.observe(myLifecycleOwner) { event: Event<MyPayload> ->
    event.getContentIfNotHandled()?.let {
        handleEvent(it)
    }
}

另一个可能的问题是,您可能不小心触发了两次事件,如果不看大图就很难说。

一种快速的解决方法是从适配器中删除重复项,以使您只需将ArrayList更改为HashSet

private Set<DisplayCourse> courseList

只需将适配器构造函数中的项目传递为HashSet