FragmentPagerAdapter - 如何处理方向更改?

时间:2013-07-13 10:49:44

标签: android android-fragments fragmentpageradapter

我使用包含多个片段的FragmentPagerAdapter,这些片段需要通知database的更改。我通过迭代实现回调接口的片段并调用refreshData()方法来完成此操作。

这可以正常工作,直到设备改变方向。方向更改后,即使方法调用似乎有效,片段UI也不会明显刷新。

从我到目前为止所读到的,这是因为FragmentPagerAdapter处理片段生命周期而接收回调的片段不是实际显示的片段。

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

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

4 个答案:

答案 0 :(得分:56)

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

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

答案 1 :(得分:0)

难道不能只在AndroidManifest.xml中的Activity上设置android:configChanges标志以防止重新创建活动吗?

<activity
    android:name="com.example.test.activity.MainActivity"
    android:configChanges="orientation|screenSize|keyboardHidden"/>

此外,您还可以找到更多的可能性: https://android.jlelse.eu/handling-orientation-changes-in-android-7072958c442a

答案 2 :(得分:0)

我在onResume方法中重新创建了寻呼机适配器:

override fun onResume() {
    super.onResume()
    val viewPager = findViewById<ViewPager>(R.id.my_view_pager)
    viewPager.adapter = MyPagerAdapter(supportFragmentManager)
}

答案 3 :(得分:-1)

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

覆盖适配器中的getItemPostion()方法

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

我的FragmentStatePagerAdapater(我的适配器)只包含一种类型的片段,但我想,您可以使用instanceof(对于更多类型的片段)然后使用强制转换或每个片段都会实现与方法refresh()

的接口

然后在片段中添加方法refresh()并使用此实现:

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

    }

这对我有用。 我的看法: 问题出现了,当设备改变方向时,适配器被破坏,但是片段仍然在内存中,系统尝试在方向改变后重用它们,但片段中包含的视图也被破坏,片段需要和#34;重新&#34; (调用onCreateView方法)。也许我错了,所以请纠正我....

(对不起我的英文)