我使用一个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();
}
我使用每个片段内的广播接收器临时修复了此问题,但是此解决方案似乎很浪费,可能会导致内存泄漏。如何正确解决此问题?我在横向模式下使用了不同的布局和逻辑,因此我想在更改方向后使用新创建的片段。
是的,就像您说的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;
}
难道不能只在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
我在onResume方法中重新创建了寻呼机适配器:
override fun onResume() {
super.onResume()
val viewPager = findViewById<ViewPager>(R.id.my_view_pager)
viewPager.adapter = MyPagerAdapter(supportFragmentManager)
}
我在工作解决方案中遇到类似的问题:在活动中,有一个适配器调用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);
}
方法)。也许我错了,所以请纠正我...。
(对不起我的英语)