FragmentPagerAdapter – 如何处理方向更改?

我使用一个FragmentPagerAdapter,其中包含需要通知有关数据库更改的几个片段。 我通过迭代实现callback接口的片段并调用refreshData()方法来完成此操作。

这工作得很好,直到设备改变方向。 方向更改后,即使方法调用似乎工作,片段UI不可见刷新。

从我迄今为止读到的情况来看,这是因为FragmentPagerAdapter处理片段生命周期,而接收callback的片段并不是实际显示的片段。

private class DataPagerAdapter extends FragmentPagerAdapter { private DataFragment[] fragments = new DataFragment[] { new FooDataFragment(), BarDataFragment()}; public DataPagerAdapter(android.support.v4.app.FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return fragments[position]; } @Override public int getCount() { return fragments.length; } public DataFragment[] getFragments() { return fragments; } } protected void refreshData() { for (DataFragment dataFragment : mPagerAdapter.getFragments()) { dataFragment.refreshData(); } 

我使用每个片段内的广播接收器临时解决了这个问题,但是这个解决scheme似乎是浪费的,可能会造成内存泄漏。 如何正确解决这个问题? 我在横向模式下使用不同的布局和逻辑,所以我想在方向更改后使用新创build的片段。

Solutions Collecting From Web of "FragmentPagerAdapter – 如何处理方向更改?"

是的,就像你说的FragmentManager处理方向改变后的片段,所以不调用适配器中的getItem 。 但是您可以重写方法instantiateItem() ,即使在方向更改后也会调用该方法,并将Object转换为Fragment并将其保存到数组中。

  @Override public Object instantiateItem(ViewGroup container, int position) { DataFragment fragment = (DataFragment) super.instantiateItem(container, position); fragments[position] = fragment; return fragment; } 

我有类似的问题,我的工作解决scheme:在活动,其中是一个适配器调用adapter.notifyDataSetChanged();

在您的适配器中重写getItemPostion()方法

 @Override public int getItemPosition(Object object) { MyFragment frag = (MyFragment)object; frag.refresh(); return POSITION_UNCHANGED; } 

我的FragmentStatePagerAdapater (我的适配器)只包含一种types的片段,但我认为,你可以使用instanceof (用于更多types的片段),然后使用强制转换或每个片段将实现接口与方法refresh()

然后在你的Fragment中添加方法refresh() )并使用这个实现:

 public void refresh() { LayoutInflater inflater = LayoutInflater.from(getActivity()); ViewGroup viewGroup = (ViewGroup) getView(); viewGroup.removeAllViewsInLayout(); View view = onCreateView(inflater, viewGroup, null); viewGroup.addView(view); } 

这对我有效。 我的观点:问题出现了,当设备改变方向时,适配器被破坏,但是碎片仍然在内存中,系统尝试在方向改变后重用它们,但碎片中包含的视图也被破坏,碎片需要要“重新创build”(调用onCreateView方法)。 也许我错了,所以请纠正我… …。

(对不起我的英语不好 )