Intereting Posts
Почему я бы никогда не использовал параметр BitPapgeable BitmapFactory? MaxWidth не работает с fill_parent Как получить ссылку на продукт в приложении под приложениями, указанными для учетной записи издателя? Поддиректория Android 4.0 (раздел) Стиль стилей Библиотека распознавания лиц в android AssertionFailedError: <класс> не имеет открытого конструктора Использовать startActivityForResult из неактивных Android Hardware Acceleration – использовать или не использовать? Ошибка сокета на уровне студии Android, слияние манифеста Как задержать цикл в android без использования thread.sleep? Изменение языкового стандарта эмулятора Android автоматически Граница формы Android с градиентом Могу ли я иметь «мягкую клавиатуру» «adjustResize» и панель инструментов за панель состояния одновременно? Зачем использовать фрагменты? Решение для локального кэширования изображений для Android: Square Picasso vs Universal Image Loader

Элементы RecyclerView не меняются

У меня есть RecyclerView в фрагменте, который повторяется в TabLayout. У меня проблема с неизменным представлением в RecyclerView. На каждой вкладке у меня есть прядильщик. Я хочу изменить данные, когда элементы-счетчики будут выбраны.

Мои случаи:

  1. При переключении между вкладками – измененные элементы
  2. При выборе другого значения в счетчике на первой вкладке – элементы не изменяются . (Но данные изменяются в классе адаптера. Во-первых, он не является нулевым, а затем нулевым во время выбора. Но первые не закодированные данные не появляются, а его заменяют нулем. Найдены с использованием контрольных точек).

    Примечание. В этом случае при переключении вкладки элементы будут изменены на выбранные элементы прядильщика на предыдущей вкладке. И затем он исчезает и отображает текущие элементы на вкладке.

  3. При выборе другого значения в счетчике на последней вкладке – элементы изменены .

Класс адаптера для плеера


 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; } } 

Введите описание изображения здесь

Возникает вопрос: почему данные не изменяются при выборе опций в spinner иногда? (Посмотри мои дела)

Solutions Collecting From Web 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); } } 

Потому что onNothingSelected вызывается вместо onItemSelected при повторном выборе элемента счетчика.

Проблема в основном здесь:

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

Это не гарантирует, что фрагмент, видимый пользователю, является последней границей. Вы устанавливаете viewPager.setOffscreenPageLimit(3); Это означает, что три фрагмента за время могут быть созданы, поэтому, когда вы находитесь на фрагменте, также создаются правые и левые.

Это объясняет, почему последний работает хорошо, потому что не существует правильного фрагмента и, вероятно, последний экземпляр и привязка.

Лично я бы изменил реализацию обработки spinner внутри фрагмента страницы, поскольку он действует только на фрагмент страницы.

Решение с помощью setUserVisibleHint

Привяжите фрагмент страницы к основному, когда фрагмент станет видимым для пользователя. Обратите внимание на утечку памяти и освободите статическую ссылку

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

Решение с шиной

Еще одним быстрым решением может быть использование такой шины: http://square.github.io/otto/. Таким образом, каждый фрагмент подписывается на событие SelectedItemChanged и обновляет его. Основной фрагмент будет публиковать обновления каждый раз при изменении выбора счетчика.

Однако пример довольно большой, поэтому я не уверен, что нет других проблем. Попытайтесь поделиться полным проектом, чтобы получить более конкретную помощь.

Когда вы работаете с recycleview, полагайтесь только на ваши значения класса класса . Внесите все изменения в класс модели и создайте представления строк на основе этих полей класса модели.

Т.е. вам необходимо создать или изменить значения или просмотреть состояние на основе значений полей класса модели.

Например: если вы хотите сделать строку (позиция 30) невидимой, тогда я установлю флаг в классе модели, называемый видимостью, и поставлю его в значение false .

В этом случае всякий раз, когда просмотр перерисовывается в пользовательском интерфейсе, нам нужно будет проверить флаг и установить видимость на основе этого значения поля класса модели.

Подобным образом вы можете создавать флаги, значения содержимого, сериализованные параметры из 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) {