FragmentPagerAdapter-如何处理方向更改?

问题描述 投票:18回答:4

我使用一个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();
}

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

android android-fragments fragmentpageradapter
4个回答
58
投票

是的,就像您说的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;
 }

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


0
投票

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

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

-1
投票

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

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

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

我的FragmentStatePagerAdapater(我的适配器)仅包含一种类型的片段,但是我认为您可以使用instanceof(用于更多类型的片段),然后使用强制转换,否则每个片段都将使用方法[C0实现接口]

然后在片段中添加方法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); } 方法)。也许我错了,所以请纠正我...。

(对不起我的英语)

© www.soinside.com 2019 - 2024. All rights reserved.