0

这个问题有一些相似之处:viewPager如何在方向更改上保留片段状态?

Fragment in ViewPager on Fragment doesn't reload on orientation change

然而不同的是,我想知道的片段状态实际上是如何保留我观察了很多奇怪的事情发生。

我的看法如下:

建立一个ViewPager与FragmentPagerAdapter:

class HomeAdapter extends FragmentPagerAdapter 
{ 
    HomeAdapter(FragmentManager manager) 
    { 
     super(manager); 
    } 

    @Override 
    public Fragment getItem(int i) { 
     try { 
      return (Fragment) mTabs.get(i).getFragmentClass().newInstance(); 
     } catch (InstantiationException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mTabs.get(position).getTitle(); 
    } 

    @Override 
    public int getCount() { 
     return mTabs.size(); 
    } 
} 

在我的活动的onCreate我打电话:

setContentView(R.layout.activity_home); 
    mTabs = new ArrayList<>(); 
    mTabs.add(new SlidingTabItem("A", FragmentA.class)); 
    mTabs.add(new SlidingTabItem("B", FragmentB.class)); 

    mViewPager = (ViewPager) findViewById(R.id.viewpager); 
    mViewPager.setAdapter(new HomeAdapter(getSupportFragmentManager())); 

    mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs); 
    mSlidingTabLayout.setViewPager(mViewPager); 

现在,当设备方向改变viewPager将所有内容都重新创建,直到片段内editText字段中已更改的文本。

澄清这实际上是我想要的行为,但我不明白。

我检查了viewPager和FragmentPagerAdapter的来源。我发现FragmentPagerAdapter会搜索FragmentManager,如果该位置的Fragment已经存在。如果它调用FragmentTransaction.attach()来重新附加它。

它还deattaches使用FragmentManager.detach()的片段

据我了解这样可以保留在FragmentManager的FragmentState。然而,WHERE和WHEN是否实际得到恢复。

我尝试在包含savedInstanceState的片段中的每个生命周期方法中挂接,并以null作为savedInstanceState调用super.X,但视图仍将以相同的方式恢复。

恢复的片段似乎也忽略了在onCreateView中完成的视图更改。我尝试了以下内容:

mMajor = (EditText) contentView.findViewById(R.id.major); 
mMajor.setText("123"); 

它在第一次创建片段时起作用。然而,即使onCreateView实际上是第二次调用,但该指令显然没有任何作用,因为主要的editText不会重置为“123”。 。

有趣的是调用mMajor.getText()toString()返回类似:

[ 01-31 18:29:54.634 18540:29583 I/ActivityManager ] 

,我也想不明白。这是因为此时视图还没有完全创建?

所以我的主要问题仍然存在。什么时候该片段实际上重新创建其实例,以及为什么它会调用生命周期方法,即使它不关心结果,并且有没有任何方法可以在首次创建片段时不设置实例变量来检测此问题?

回答

2

Fragment S被ViewPager分离,他们会经过停机生命周期(onPause()onSaveInstanceState()onStop()onDestroyView()onDetach()等。)

然而,ViewPager(更具体的FragmentStatePagerAdapter)将通过与手动保存片段的状态到它自己保存的状态(拆卸碎片时)调用FragmentManager.saveFragmentInstanceState(fragment)。这很可能就是为什么你重写调用super.*(null)的方法不会影响它。

由于onCreateView()发生在onViewStateRestored()之前,它将恢复保存的状态并覆盖更改,因此您的视图的原因更改被覆盖。无论如何,你真的不应该在该方法中设置视图状态 - 只需返回视图即可。

如果您确实想知道这是否是第一次创建片段,那么检查if (savedInstanceState == null)就足够了。如果是这样,这是第一次发射。否则,它会从保存的状态重新创建它自己。

相关问题