Tab + ViewPager не обновляет вместо этого показывает странное предупреждение ожидаемое состояние 3 найдено 2

У меня есть mainactivity, который включает TabLayout с ViewPager

Я добавил 3 вкладки, и каждая вкладка имеет отдельные фрагменты, которые содержат recyclerview, и эти recyclerviews имеют флажок, который должен быть одновременно обновлен / обновлен всякий раз, когда я прокручиваю viewpager (я сохраняю выбранные позиции в общих предпочтениях и обновлениях по общим предпочтениям).

Моя проблема здесь, когда я устанавливаю флажок в tab1, tab2 не обновляет / обновляет, пока я не прокручу Recyclerview. И tab3 работает нормально. И я получаю странное предупреждение в logcat тоже.

03-05 09:35:53.345 4317-4327/com.example.rubin W/art: Suspending all threads took: 6.805ms 03-05 09:35:58.310 4317-4317/com.example.rubin W/FragmentManager: moveToState: Fragment state for Tab3{10a5f1f0 #2 id=0x7f0d00b6} not updated inline; expected state 3 found 2 03-05 09:36:01.363 4317-4317/com.example.rubin W/FragmentManager: moveToState: Fragment state for Tab1{2d9aa887 #1 id=0x7f0d00b6} not updated inline; expected state 3 found 2 

Мой пейджер-адаптер

 public class PagerAdapter1 extends FragmentStatePagerAdapter { int mNumOfTabs; public PagerAdapter1(FragmentManager fm, int NumOfTabs) { super(fm); this.mNumOfTabs = NumOfTabs; } @Override public Fragment getItem(int position) { switch (position) { case 0: return new Tab1(); case 1: return new Tab2(); case 2: return new Tab3(); default: return null; } } @Override public int getCount() { return mNumOfTabs; } } 

Tablayout OnPageChangelistener

 final PagerAdapter1 adapter = new PagerAdapter1 (getSupportFragmentManager(), tabLayout1.getTabCount(), getApplicationContext()); viewPager1.setAdapter(adapter); viewPager1.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout1)); tabLayout1.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { viewPager1.setCurrentItem(tab.getPosition()); adapter.notifyDataSetChanged(); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } }); } 

Код для каждого фрагмента.

  public class Tab1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.home_tab1_recycler, container, false); RecyclerView rv = (RecyclerView) v.findViewById(R.id.home_recyclerview); LinearLayoutManager llm = new LinearLayoutManager(getContext()); rv.setLayoutManager(llm); rv.setHasFixedSize(true); // to improve performance rv.setAdapter(new HomeManager()); // the projectdatabase manager is assigner to the RV return v; } public class HomeManager extends RecyclerView.Adapter<HomeManager.RecyclerViewHolder> { int Length,h; View v1; ArrayList<String> PROJECT_ID = new ArrayList<String>(); Set<String> set; List<String> selected; public class RecyclerViewHolder extends RecyclerView.ViewHolder { CheckBox mCheck; RecyclerViewHolder(final View itemView) { super(itemView); mCheck = (CheckBox) itemView.findViewById(R.id.PROJECT_fav); SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); set = pref.getStringSet("FAV", null); if (set != null) { selected = new ArrayList<String>(set); } else { selected = new ArrayList<String>(); } mCheck.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { h = getAdapterPosition(); check = PROJECT_ID.get(h); // for saving the project id from json. if (selected.contains(check)) { selected.remove(check); mCheck.setBackgroundResource(R.drawable.ic_favorite_white1_24dp); Snackbar snackbar = Snackbar.make(v, "Property Unfavorited", Snackbar.LENGTH_SHORT); snackbar.show(); } else { selected.add(check); mCheck.setBackgroundResource(R.drawable.ic_favorite_white_24dp); Snackbar snackbar = Snackbar.make(v, "Property Favorited", Snackbar.LENGTH_SHORT); snackbar.show(); } Log.e("HF update checked", String.valueOf(selected)); Set<String> set = new HashSet<String>(); set.addAll(selected); SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); editor.putStringSet("FAV", set); editor.commit(); } } }); @Override public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { v1 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false); return new RecyclerViewHolder(v1); } @Override public void onBindViewHolder(final RecyclerViewHolder viewHolder, int i) { SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); set = pref.getStringSet("FAV", null); if (set != null) { selected = new ArrayList<String>(set); } else { selected = new ArrayList<String>(); } Log.e("HF update UI", String.valueOf(selected)); if (String.valueOf(selected).contains(String.valueOf(PROJECT_ID.get(i)))) { viewHolder.mCheck.setBackgroundResource(R.drawable.ic_favorite_white_24dp); } else { viewHolder.mCheck.setBackgroundResource(R.drawable.ic_favorite_white1_24dp); } } @Override public int getItemCount() { //Code for Total length of json return Length; } 

FragmentPagerAdapter вызывает setUserVisibleHint(true|false) в окрестностях активного фрагмента, который изменяет состояние этих фрагментов. Это, по крайней мере, ответ на «странные предупреждающие сообщения», но это может не решить вашу проблему.

Что касается вашего комментария о том, как решить это предупреждение, я создал свой собственный FragmentPagerAdapter следующим образом:

 public abstract class AbstractTabPagerAdapter extends PagerAdapter { private static final String TAG = AbstractTabPagerAdapter.class.getCanonicalName(); private final FragmentManager mFragmentManager; private FragmentTransaction mCurTransaction; private Fragment mCurrentPrimaryItem = null; public AbstractTabPagerAdapter(FragmentManager fragmentManager) { mFragmentManager = fragmentManager; } @Override public Object instantiateItem(ViewGroup container, int position) { if (mCurTransaction == null) { throw new IllegalArgumentException("current transaction must not be null"); } String fragmentTag = makeFragmentName(container.getId(), position); Fragment fragment = (Fragment) mFragmentManager.findFragmentByTag(fragmentTag); if (fragment != null) { mCurTransaction.attach(fragment); Log.d(TAG, "Attaching existing fragment " + fragment + " at position " + position); //mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), position)); } else { fragment = getItem(position); mCurTransaction.add(container.getId(), fragment, fragmentTag); Log.d(TAG, "Attaching new fragment " + fragment + " at position " + position); } if (fragment != mCurrentPrimaryItem) { fragment.setMenuVisibility(false); //fragment.setUserVisibleHint(false); } return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (mCurTransaction == null) { throw new IllegalArgumentException("current transaction must not be null"); } mCurTransaction.detach((Fragment) object); //mCurTransaction.remove((Fragment)object); } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { //super.setPrimaryItem(container, position, object); Fragment fragment = (Fragment) object; if (fragment != mCurrentPrimaryItem) { Log.d(TAG, "set Primary item " + position + " to " + fragment); if (mCurrentPrimaryItem != null) { mCurrentPrimaryItem.setMenuVisibility(false); // this command unexpectedly changes the state of the fragment which leads to a warning message and possible some strange behaviour //mCurrentPrimaryItem.setUserVisibleHint(false); } if (fragment != null) { fragment.setMenuVisibility(true); //fragment.setUserVisibleHint(true); } mCurrentPrimaryItem = fragment; } } @Override public boolean isViewFromObject(View view, Object fragment) { return ((Fragment) fragment).getView() == view; } public abstract Fragment getItem(int position); @Override public void startUpdate(ViewGroup container) { super.startUpdate(container); if (mCurTransaction != null) { throw new IllegalArgumentException("current transaction must not be null"); } mCurTransaction = mFragmentManager.beginTransaction(); Log.d(TAG, "FragmentTransaction started"); } @Override public void finishUpdate(ViewGroup container) { if (mCurTransaction != null) { mCurTransaction.commit(); mCurTransaction = null; //mFragmentManager.executePendingTransactions(); Log.d(TAG, "FragmentTransaction committed"); } else { throw new IllegalArgumentException("current transaction must not be null"); } } private String makeFragmentName(int viewId, int position) { if (viewId <= 0) throw new IllegalArgumentException("viewId " + viewId); return "tabpageradptr:" + getPageTitle(position) + ":" + viewId + ":" + position; } } 

Предупреждающее сообщение исчезло, и в настоящее время я не испытываю недостатков – но я все еще в центре исследований.

Я потратил много времени на эту проблему. Проблема в том, что вы пытаетесь обновить viewpager в прослушивателе OnPageChangeListener, это вызовет предупреждение

Не обновляется в очереди

Решение:

Все изменения данных и вид обновления должны вызывать OnPageChangeListener, например: onCreateView of Fragment

Мое предупреждение исчезло! И обновление viewpager completeelly

Поздно, но я решил, что лучше всего использовать FragmentPagerAdapter, хотя он не устраняет предупреждения, но решает эту задачу, если кто-нибудь может сообщить мне, что на самом деле означает это предупреждение и что на самом деле вызывает предупреждение, это было бы наилучшим образом ,

Сначала во всех фрагментах, используемых в методе создания viewpager, как показано ниже.

 Public void updateView () {
   // Обновляем все виды или данные, которые вы хотите обновить.
 }

Также переопределите метод setUserVisibleHint, который используется в FragmentPagerAdapter для уведомления, является ли фрагмент видимым для пользователя или нет.

  @Override
     Public void setUserVisibleHint (boolean isVisibleToUser) {
         This.isVisibleToUser = isVisibleToUser;
         super.setUserVisibleHint (isVisibleToUser);
     }

Наконец, в вашем фрагменте добавьте следующий код, чтобы обновить представление / дату, когда фрагмент будет виден.

 @Override
     Public void onStart () {
             If (isVisibleToUser)
                 updateView ();
     }

Затем реализуйте это в своем TabFragment или Activity

 Viewpager.addOnPageChangeListener (новый ViewPager.OnPageChangeListener () {
             @Override
             Public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) {

             }

             @Override
             Public void onPageSelected (int position) {

                 Переключатель (позиция) {
                     Case 0: {
                          ((Фрагмент) mFragmentList.get (0)). UpdateView ();
                         ломать;
                     }
                     Дело 1: {
                          ((Фрагмент) mFragmentList.get (1)). UpdateView ();
                         ломать;
                     }
                 }
             }

Это позаботится о том, чтобы обновлять данные согласованно, либо прокручивать, либо щелкнуть вкладку, если кто-либо обнаружит какие-либо проблемы или ошибки, прокомментируйте и дайте мне знать или не стесняйтесь редактировать решение

И я проголосовал за решение выше, которое подтолкнуло меня к применению этого решения. Спасибо @mikes

Это не важно. Это только предупреждение. Попробуйте изменить фон макета ViewPager на нуль (не задавать фон).

Одновременно загружаются соседние вкладки пейджера. Таким образом, ваши действия на вкладке 1 не отразятся на вкладке 2 с момента ее загрузки. Вы должны использовать приемники Broadcast для решения этой проблемы. Передача события на вкладке 1 и получение события на вкладке 2

"W/FragmentManager: moveToState: … expected state 3 found 2" предупреждение может быть проигнорировано и удалено в Support Library v24.0.0.

Цитата из официального ответа разработчика:

Вам не нужно ничего делать; Это только сообщение информационного журнала. […]

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

Закрытие комментариев, поскольку проблема журнала была решена для будущей версии.

Intereting Posts