RecyclerView项目没有变化

我在一个片段中有一个RecyclerView ,它在TabLayout中重复出现。 我在RecyclerView中遇到了视图不变的问题。 我在每个标签上都有一个微调器。 我想在选择微调器项时更改数据。

我的案子:

  1. 在标签之间切换时 – 项目已更改
  2. 在第一个选项卡中在微调器中选择另一个值时 – 项目未更改 。 (但是数据在适配器类中发生了变化。首先,它在选择期间不为null然后为null。但是第一个没有空的数据没有出现,它被替换为null。使用断点find它)。

    注意:在这种情况下,切换选项卡时,项目将更改为上一个选项卡中的微调器选定项目。 然后它消失并在选项卡中显示当前项目。

  3. 在最后一个选项卡中在微调器中选择另一个值时 – 项目已更改

我的视图寻呼机适配器类


 public class StudentViewPagerAdapter extends FragmentStatePagerAdapter { private final List mFragmentList = new ArrayList(); private final List mFragmentTitleList = new ArrayList(); public StudentViewPagerAdapter(FragmentManager fm) { super(fm); } public void addFragment(StudentList fragment,Clazz clazz){ mFragmentList.add(fragment); mFragmentTitleList.add(clazz); } @Override public Fragment getItem(int position) { return StudentList.newInstance(mFragmentTitleList.get(position)); } @Override public int getCount() { return mFragmentList.size(); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position).getName(); } } 

我的RecyclerView适配器类

 public class PeopleAdapter extends RecyclerView.Adapter implements View.OnClickListener { private List dataList; private Context context; private Clicker clicker; public PeopleAdapter(List data, Context context, Clicker clicker) { this.dataList = data; this.context = context; this.clicker = clicker; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.people_list_item, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { Student data=dataList.get(position); holder.email.setText(data.getEmail()); holder.name.setText(data.getName()); holder.phone.setText(data.getPhone()); Glide.with(context).load(Method.getImageUrl(MyConfiguration.STUDENT_IMAGE_URL, data.getStudentId())).asBitmap().into(holder.profilePic); holder.edit.setOnClickListener(this); holder.edit.setTag(position); } @Override public int getItemCount() { return dataList.size(); } @Override public void onClick(View v) { clicker.OnItemClicked((int) v.getTag(),null); } static class MyViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.name) TextView name; @BindView(R.id.email) TextView email; @BindView(R.id.phone) TextView phone; @BindView(R.id.image) ImageView profilePic; @BindView(R.id.imageedit) ImageView edit; MyViewHolder(View view) { super(view); ButterKnife.bind(this,view); } } } 

标签片段

  public class StudentList extends Fragment implements SectionChanger { @BindView(R.id.studentlist) RecyclerView mRecyclerview; CompositeDisposable disposable; private Unbinder unbinder; private Clazz clazz; private Requester requester; public StudentList() { StudentInformation.bindSectionChangeListener(this); } public static StudentList newInstance(Clazz clazz) { StudentList fragment=new StudentList(); Bundle args = new Bundle(); args.putSerializable(MyConfiguration.SECTIONS, clazz); fragment.setArguments(args); return fragment; } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); disposable.clear(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_student_list, container, false); unbinder = ButterKnife.bind(this, view); LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerview.setLayoutManager(mLayoutManager); initializeRetrofit(); if (getArguments() != null) { clazz = (Clazz) getArguments().getSerializable(MyConfiguration.SECTIONS); loadStudentJson(clazz != null ? clazz.getClassId() : null, clazz != null ? clazz.getSections().get(0).getSectionId() : null); } return view; } /https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* Load students list https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*/ public void loadStudentJson(String class_id,String section_id) { disposable = new CompositeDisposable(requester.getStudentsInSection(class_id,section_id) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe( this::handleResponse, this::handleError ) ); } private void handleResponse(List list) { PeopleAdapter adapter=new PeopleAdapter(list, getActivity(), (position, name) -> Toast.makeText(getActivity(), position, Toast.LENGTH_LONG).show()); mRecyclerview.setAdapter(adapter); adapter.notifyDataSetChanged(); } private void handleError(Throwable error) { Toast.makeText(getActivity(), "Error " + error.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } @Override public void ChangeData(Section section) { loadStudentJson(section.getClassId(),section.getSectionId()); } public void initializeRetrofit(){ HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); CookieHandler handler=new Cookies(getActivity()); //ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getActivity())); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(interceptor) .cookieJar(new JavaNetCookieJar(handler)) .build(); requester = new Retrofit.Builder() .baseUrl(MyConfiguration.BASE_URL) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(JacksonConverterFactory.create()) .client(client) .build().create(Requester.class); } } 

Viewpager设置片段

 public class StudentInformation extends Fragment implements TabLayout.OnTabSelectedListener, AdapterView.OnItemSelectedListener { // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, eg ARG_ITEM_NUMBER private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; private Unbinder unbinder; // TODO: Rename and change types of parameters private String mParam1; private String mParam2; CompositeDisposable disposable; List
sectionsList=new ArrayList(); private OnConnectingFragments mListener; @BindView(R.id.tabs) TabLayout mTabLayout; @BindView(R.id.viewpager) ViewPager viewPager; @BindView(R.id.secSelector) Spinner spinner; @BindView(R.id.className) TextView className; private static SectionChanger sectionChanger; public StudentInformation() { // Required empty public constructor } /https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* Use this factory method to create a new instance of https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* this fragment using the provided parameters. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* @param param1 Parameter 1. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* @param param2 Parameter 2. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* @return A new instance of fragment StudentInformation. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*/ // TODO: Rename and change types and number of parameters public static StudentInformation newInstance(String param1, String param2) { StudentInformation fragment = new StudentInformation(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); disposable.clear(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment_student_information, container, false); unbinder = ButterKnife.bind(this, view); LoadDataAndSetupViewPager(); //setupViewPager(viewPager); mTabLayout.setupWithViewPager(viewPager); mTabLayout.addOnTabSelectedListener(this); spinner.setOnItemSelectedListener(this); // ArrayAdapter arrayAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_dropdown_item, MyConfiguration.CLASS_SECTIONS); // spinner.setAdapter(arrayAdapter); return view; } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed(Fragment fragment,String tag) { if (mListener != null) { mListener.onClickedMenu(fragment,tag); } } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnConnectingFragments) { mListener = (OnConnectingFragments) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } /https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* This interface must be implemented by activities that contain this https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* fragment to allow an interaction in this fragment to be communicated https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* to the activity and potentially other fragments contained in that https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* activity. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*

https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/* See the Android Training lesson Communicating with Other Fragments for more information. https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*/ /https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*private void setupViewPager(ViewPager viewPager) { StudentViewPagerAdapter adapter = new StudentViewPagerAdapter(getFragmentManager()); //adapter.addFragment(new StudentList(),"exam"); for (String claz: MyConfiguration.CLASS) adapter.addFragment(new StudentList(), claz); viewPager.setAdapter(adapter); }https://stackoverflow.com/questions/42921034/recyclerview-items-are-not-changing/*/ @OnClick(R.id.add) public void OnClicked(LinearLayout view){ onButtonPressed(new AddStudent(),"addStudent"); } @Override public void onTabSelected(TabLayout.Tab tab) { className.setText(String.format(getString(R.string.class_name), tab.getPosition()+1)); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } public void LoadDataAndSetupViewPager() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getActivity())); OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); Requester requester=new Retrofit.Builder() .baseUrl(MyConfiguration.BASE_URL) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(JacksonConverterFactory.create()) .client(client) .build().create(Requester.class); disposable=new CompositeDisposable(requester.getClasses() ////GETTING CLASSES//// .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .flatMapIterable(clazzs -> clazzs) .flatMap(clazz -> requester.getDivision(clazz.getClassId()) ////GETTING SECTIONS//// .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .flatMapIterable(sections -> sections) .doOnNext(section -> {sectionsList.add(section); Log.v("section_id",section.getSectionId());}) .takeLast(1) .map(section -> clazz) ) .doOnNext(clazz -> {clazz.setSections(sectionsList); Log.v("List Size",sectionsList.size()+""); sectionsList=new ArrayList(); }) .toList() .subscribe(this::SetupViewPager, throwable -> Log.e("retroerror",throwable.toString()))); } public void SetupViewPager(List classList){ StudentViewPagerAdapter adapter = new StudentViewPagerAdapter(getFragmentManager()); //adapter.addFragment(new StudentList(),"exam"); for (Clazz claz: classList){ adapter.addFragment(new StudentList(), claz); } viewPager.setAdapter(adapter); viewPager.setOffscreenPageLimit(3); viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { super.onPageSelected(position); List

sections=classList.get(position).getSections(); ArrayAdapter
arrayAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_dropdown_item, sections); spinner.setAdapter(arrayAdapter); } }); } @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { Section section= (Section) parent.getItemAtPosition(position); sectionChanger.ChangeData(section); } @Override public void onNothingSelected(AdapterView parent) { } public static void bindSectionChangeListener(SectionChanger changer){ sectionChanger=changer; } }

在此处输入图像描述

问题是: 为什么有时候在微调器中选择选项时数据会保持不变? (看我的情况)

尝试使用getChildFragmentManager()而不是getFragmentManager()将解决您的问题

我认为你应该实现如下的onNothingSelected()

 Section mCurrentSection; @Override public void onNothingSelected(AdapterView parent) { int position = parent.getSelectedItemPosition(); Section section= (Section) parent.getItemAtPosition(position); if (mCurrentSection == null || !mCurrentSection.equals(section)) { mCurrentSection = section; sectionChanger.ChangeData(section); } } 

因为,当您重新选择一个微调器项时,会调用onNothingSelected而不是onItemSelected。

问题主要在于:

  public StudentList() { StudentInformation.bindSectionChangeListener(this); } 

这并不能保证用户可见的片段是最后一个绑定的片段。 你设置viewPager.setOffscreenPageLimit(3); 这意味着每次可以实例化三个片段,因此当您在片段上时,也会创建右侧和左侧片段。

这解释了为什么最后一个很好用,因为没有一个正确的片段,可能是最后一个被实例化和绑定的片段。

我个人会更改处理页面片段内的微调器的实现,因为它只对页面片段起作用。

使用setUserVisibleHint的解决方案

当片段变得对用户可见时,将页面片段绑定到主片段。 注意内存泄漏并释放静态参考

  @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ StudentInformation.bindSectionChangeListener(this); } } 

用公共汽车解决方案

另一个快速解决方案可能是使用这样的总线: http : //square.github.io/otto/这样每个片段都会订阅一个事件SelectedItemChanged并刷新它们自己。 每次更改微调器时,主片段都会发布更新。

然而,这个例子非常大,所以我不能确定没有其他问题。 尝试共享一个完整的项目以获得更具体的帮助。

当您使用recycleview时,仅依赖于您的模型类字段值。 对模型类进行所有更改并基于此模型类字段创建行视图。

即,您必须根据模型类字段的值创建或更改值或查看状态。

例如:如果你想使一行(位置30)不可见,那么我将在模型类中设置一个名为visibility的标志并将其设置为false

在这种情况下,只要在UI中重新查看视图,我们就必须检查标志并根据该模型类字段值设置可见性。

像这样你可以在模型类中创建标志,内容值,API等序列化参数。 此方法将通过用户交互和API更改使您的reclycleview更加一致。

检查您的StudentViewPagerAdapter

  @Override public Fragment getItem(int position) { return mFragmentList.get(position).newInstance(mFragmentTitleList.get(position)); } 

你为什么再打电话给newInstance

用以下内容替换它, return mFragmentList.get(position);

首先,检查之后是否添加此行

 setadapter : adapter.notifyDataSetChanged(); 

另一种方法是使最终的MyViewHolder持有者和int位置

例。

 public void onBindViewHolder(final MyViewHolder holder, final int position) {