问题描述
我有主要活动,其中有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