Tab + ViewPager没有更新,而是显示奇怪的警告预期状态3find2

我有一个主要活动,其中包括与ViewPager的TabLayout

我已经添加了3个选项卡,每个选项卡都有单独的包含recyclerview的片段,这些recyclerviews有一个checkbox,每当我滑动viewpager(我保存共享首选项中的检查位置和通过共享首选项更新)应该同时更新/刷新。

我的问题是每当我检查tab1的checkbox,tab2不更新/刷新,直到我向下滚动回收站。 和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 

我的PagerAdapter

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

Solutions Collecting From Web of "Tab + ViewPager没有更新,而是显示奇怪的警告预期状态3find2"

FragmentPagerAdapter在活动片段的邻域上调用setUserVisibleHint(true|false) ,这会改变这些片段的状态。 这至less是“怪异的警告信息”的答案,但它可能无法解决你的问题。

关于如何解决这个警告信息的注释,我已经创build了我自己的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; } } 

警告信息已经消失,目前我没有遇到任何缺陷 – 但我仍然处于研究的中间。

我花了很多时间来解决这个问题。 问题是您尝试更新OnPageChangeListener监听器中的viewpager,它会引发警告

不在线更新

解:

所有数据更改和更新视图应调用OnPageChangeListener,例如:片段的onCreateView

我的警告消失了! 并且viewpager更新完整

它的后期,但我认为使用FragmentPagerAdapter最好的出路,虽然它并没有消除警告,但它解决的目的,如果任何人都可以告诉我什么是警告实际上意味着什么,实际上是什么引起的警告,这将是我的最大利益。

首先在viewpager中使用的所有片段创build方法如下。

 public void updateView(){
   / /更新您想要更新的任何意见或数据
 }

还要覆盖在FragmentPagerAdapter中使用的方法setUserVisibleHint来通知片段是否对用户可见。

  @覆盖
     public void setUserVisibleHint(boolean isVisibleToUser){
         this.isVisibleToUser = isVisibleToUser;
         super.setUserVisibleHint(isVisibleToUser);
     }

最后在片段中添加下面的代码,以便在片段可见时更新视图/date。

 @覆盖
     public void onStart(){
            如果(isVisibleToUser)
                更新视图();
     }

然后在你的TabFragment或者Activity中实现这个

 viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){
             @覆盖
             public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels){

             }

             @覆盖
             public void onPageSelected(int position){

                开关(位置){
                    情况0:{
                          ((Fragment)mFragmentList.get(0))。updateView();
                        打破;
                     }
                    情况1: {
                          ((Fragment)mFragmentList.get(1))。updateView();
                        打破;
                     }
                 }
             }

这将负责连续更新数据,无论是刷卡还是点击标签,如果有人发现任何问题或错误,请发表评论,让我知道或随意编辑解决scheme

我已经投了上面的解决scheme给了我的方法来应用这个解决scheme。 谢谢@mikes

这并不重要。 这只是一个警告。 请尝试将ViewPager布局的背景更改为空(不设置背景)。

鉴于寻呼机相邻的选项卡同时加载。 所以你的行为在选项卡1中不会反映在标签2中,因为它已经被加载了。 你应该使用广播接收机来解决这个问题。 在标签1中广播事件并在标签2中接收事件

支持库v24.0.0中的"W/FragmentManager: moveToState: … expected state 3 found 2"警告可以忽略并被删除。

从官方开发人员的引用回答 :

你不需要做任何额外的事情; 这只是一个信息日志消息。 […]

这里描述的日志本身不会影响行为。 如果您有其他问题,请打开一个新的错误; 将同一个bug中的不同问题混为一谈使得这些单独的问题更难追踪。

由于日志问题已在未来发行版中解决,因此closures注释。