这是我的问题,我有一个活动,其中包含一个使用ViewPager的Fragment(FragmentStatePagerAdapter),当Activity首次加载时,所有工作都很完美,但是当设置setRetainInstance(true)到父片段时(带有寻呼机的那个),并且活动的方向发生变化,它会导致
java.lang.IllegalStateException:No activity
尝试添加已保存的片段时,代码如下:
的活动:
public class DetailActivity{
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout_with_progress_container);
...
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState != null) {
Fragment f = fm.findFragmentById(R.id.container);
if(f instanceof DetailPagerFragment){
detailPagerFragment = (DetailPagerFragment) f;
}
}
}
@Override
protected void onPostResume() {
super.onPostResume();
//If fragment is null, create a new instance
if(detailPagerFragment==null){
detailPagerFragment =
DetailContainerFragment.newInstance(details, initialPosition);
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, detailPagerFragment);
ft.commit();
}
注意:我必须在onCreate上保存片段实例,因为当代码到达onStart时,此片段的引用为null(此问题与它有关的时间并不重要NavigationDrawer),所以我需要手动保存片段的实例。
活动布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"/>
</RelativeLayout>
ViewPager Fragmentm此类扩展为DetailPagerFragment,它是一个自定义的分页器片段,它只包含寻呼机的公共代码(例如视图膨胀,使用inflateView方法),这就是为什么寻呼机被添加到片段上而不是直接参加活动:
public class DetailContainerFragment extends DetailPagerFragment {
List<Detail> details;
public static DetailContainerFragment newInstance(List<Detail> details,int selectedPosition) {
DetailContainerFragment df = new DetailContainerFragment();
df.setSelectedPosition(selectedPosition);
df.setDetails(details);
return df;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
/**
* Inflates the view to be used by this fragment
*
* @param inflater
* Inflater to use
* @return Inflated view
*/
@Override
public View inflateView(LayoutInflater inflater) {
return inflater.inflate(R.layout.detail_pager_fragment, null);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
DetailStatePagerAdapter detailStatePagerAdapter = new DetailStatePagerAdapter(getChildFragmentManager());
setPagerAdapter(detailStatePagerAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
private class DetailStatePagerAdapter extends FragmentStatePagerAdapter {
public DetailStatePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(details.get(position));
}
@Override
public CharSequence getPageTitle(int position) {
return details.get(position).getTitle();
}
@Override
public int getCount() {
return details.size();
}
}
}
答案 0 :(得分:6)
我在ViewPager中遇到了与子片段类似的问题。
父片段创建了与ViewPager一起使用的子片段的新实例,而适配器保留了在配置更改之前使用的旧子片段的实例。
在用它初始化适配器之前,我最终清理了ChildFragmentManager:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPager = (ViewPager) view.findViewById(R.id.pager);
cleanChildFragments(getChildFragmentManager());
mPagerAdapter = new MyPagerAdapter(getChildFragmentManager(), getTabFragments());
mPager.setAdapter(mPagerAdapter);
}
/**
* This is necessary to have a clean ChildFragmentManager, old fragments might be called otherwise
* @param childFragmentManager
*/
private void cleanChildFragments(FragmentManager childFragmentManager) {
List<Fragment> childFragments = childFragmentManager.getFragments();
if (childFragments != null && !childFragments.isEmpty()) {
FragmentTransaction ft = childFragmentManager.beginTransaction();
for (Fragment fragment : childFragments) {
ft.remove(fragment);
}
ft.commit();
}
}
也许这有助于某人...