RecyclerView项目不会更改

我有一个在TabLayout中重复的片段中的RecyclerView。 我有在RecyclerView中的视图不变的问题。 每个标签上都有一个微调框。 我想在select微调项目时更改数据。

我的情况:

  1. 当切换标签 – 项目改变
  2. 当在第一个选项卡中的微调器中select另一个值 – 项目没有改变 。 (但是数据在适配器类中是变化的,也就是说,首先在select过程中不是null,那么就是null,但是第一个没有空的数据不会出现,用null代替,用断点find)。

    注意:在这种情况下,切换选项卡时,项目会变成前一选项卡中的微调选框选项。 然后它消失并在选项卡中显示当前项目。

  3. 当在最后一个选项卡中的微调框中select另一个值 – 项目更改

我的浏览器适配器类


 public class StudentViewPagerAdapter extends FragmentStatePagerAdapter { private final List<StudentList> mFragmentList = new ArrayList<>(); private final List<Clazz> 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<PeopleAdapter.MyViewHolder> implements View.OnClickListener { private List<Student> dataList; private Context context; private Clicker clicker; public PeopleAdapter(List<Student> 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; } /** * Load students list */ 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<Student> 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<Section> 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 } /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment StudentInformation. */ // 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<String> 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; } /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ /*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); }*/ @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<Clazz> 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<Section>sections=classList.get(position).getSections(); ArrayAdapter<Section> 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; } } 

在这里输入图像说明

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

Related of "RecyclerView项目不会更改"

尝试使用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); } } 

因为当你重新select一个微调项时,onNothingSelected被调用而不是onItemSelected。

问题主要在于:

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

这并不能保证用户可见的片段是最后的界限。 你设置viewPager.setOffscreenPageLimit(3); 这意味着每次有三个片段可以被实例化,所以当你在一个片段上时,也会创build右边和左边的片段。

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

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

带有setUserVisibleHint的解决scheme

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

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

与公共汽车解决scheme

另一个快速的解决scheme可能是使用像这样的总线: http : //square.github.io/otto/这样每个片段将订阅一个事件SelectedItemChanged并刷新它们自我。 主片段将在每次更改微调器选项时发布更新。

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

当你使用recycleview时只依靠你的模型类的提交值。 对模型类进行所有更改,并根据此模型类字段创build行视图。

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

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

在这种情况下,无论何时在UI中重新绘制视图,我们将不得不检查标志并根据该模型类字段值设置可见性。

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

检查你的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) {