gpt4 book ai didi

java - FragmentStatePagerAdapter、childFragmentManager 和方向更改组合不好?

转载 作者:太空宇宙 更新时间:2023-11-03 12:34:30 25 4
gpt4 key购买 nike

这是我的问题,我有一个 Activity,其中包括一个使用 (FragmentStatePagerAdapter) 的 ViewPager 的 Fragment,当 Activity 第一次加载时一切正常,但是当将 setRetainInstance(true) 设置为父 fragment 时(带有寻呼机的那个),并且 Activity 的方向发生变化,这会导致

java.lang.IllegalStateException: No activity

尝试添加已保存的 fragment 时,代码如下:

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 上保存 fragment 实例,因为当代码到达 onStart 时,该 fragment 的引用为空(这个问题并不重要,因为它与NavigationDrawer),所以我需要手动保存 fragment 的实例。

Activity 布局:

    <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,这是一个自定义分页器 fragment ,它只包装了分页器的公共(public)代码(例如 View 膨胀,使用 inflateView 方法),这就是分页器添加在 fragment 上而不是直接添加的原因到 Activity :

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

最佳答案

我在 ViewPager 中遇到了类似的子 fragment 问题。

父 fragment 创建了子 fragment 的新实例以与 ViewPager 一起使用,而适配器保留了在配置更改之前使用的旧子 fragment 的实例。

在用它初始化适配器之前,我最终清理了 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();
}
}

也许这对某人有帮助...

关于java - FragmentStatePagerAdapter、childFragmentManager 和方向更改组合不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23839189/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com