20

我使用一个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

4 回答 4

59

是的,就像您说的 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;
 }
于 2013-07-13T11:04:53.597 回答
0

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

override fun onResume() {
    super.onResume()
    val viewPager = findViewById<ViewPager>(R.id.my_view_pager)
    viewPager.adapter = MyPagerAdapter(supportFragmentManager)
}
于 2019-10-05T16:53:49.583 回答
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

于 2019-02-15T10:18:11.577 回答
-1

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

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

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

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

然后refresh()在您的 Fragment(s) 中添加方法并使用此实现:

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

    }

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

(对不起我的英语不好 )

于 2014-10-13T19:15:41.277 回答