当重新加载时,ViewPage Fragment消失

8
以下是布局。
测试.xml。
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="Click"
        android:id="@+id/button"
        />

<!-- Framelayout to display Fragments -->
<FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

test_detail.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Hello"
        android:id="@+id/textView" android:layout_gravity="center_horizontal"/>
</LinearLayout>

常见的视图翻页布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/MainViewerPage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <android.support.v4.view.PagerTabStrip
            android:id="@+id/TitlePageTabStrip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </android.support.v4.view.ViewPager>

</LinearLayout>

以下是我的Activity代码。
    public class TestFragmentActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.test);

    Button button = (Button) this.findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.frame_container, new HomeFragment()).commit();

        }
    });

    }

    public class HomeFragment extends Fragment {
    private PagerAdapter _adapter;

    public HomeFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);

        this._adapter = new PagerAdapter(TestFragmentActivity.this);
        this._adapter.add(new DetailFragment());

        ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
        pager.setAdapter(this._adapter);

        return view;
    }
    }


    public class DetailFragment extends Fragment {

    public DetailFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.test_detail, container, false);

        return rootView;
    }
    }


    public class PagerAdapter extends FragmentPagerAdapter {
    private ArrayList<Fragment> _fragments;

    public PagerAdapter(FragmentActivity activity) {
        super(activity.getSupportFragmentManager());

        this._fragments = new ArrayList<Fragment>();
    }

    public void add(Fragment fragment) {
        this._fragments.add(fragment);
    }

    @Override
    public Fragment getItem(int position) {
        return this._fragments.get(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "Test";
    }

    @Override
    public int getCount() {
        return 1;
    }


    }
}

当我点击按钮时,ViewPager中的片段被显示出来。
但是当我再次点击该按钮时,该片段消失了。
请帮帮我。

仅适用于Fragment中的getChildFragmentManager。我不知道该如何使用。请告诉我您的想法? - Eagle
这并不能解决你的问题,但是改变FragmentPagerAdapter的名称是必要的,因为PagerAdapter是Android框架内置的类,将其改为类似于MyPagerAdapter的名称。在未来,你可能会对导入等方面感到困惑... - mmlooloo
我已经发布了缺失的布局。 - Eagle
5个回答

23

尝试使用以下代码:

在您的适配器构造函数中更改此处:

public class MyPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;

public MyPagerAdapter(FragmentManager activity) {
    super(activity);

    this._fragments = new ArrayList<Fragment>();
}

public void add(Fragment fragment) {
    this._fragments.add(fragment);
}

@Override
public Fragment getItem(int position) {
    return this._fragments.get(position);
}

@Override
public CharSequence getPageTitle(int position) {
    return "Test";
}

@Override
public int getCount() {
    return 1;
}


}

当您想创建适配器时,请将getChildFragmentManager()发送到其构造函数中

public class HomeFragment extends Fragment {
private MyPagerAdapter _adapter;

public HomeFragment() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
    ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);

    this._adapter = new MyPagerAdapter(getChildFragmentManager());
    this._adapter.add(new DetailFragment());


    pager.setAdapter(this._adapter);


    return view;
}
}
我测试了它并且它工作正常,如果有任何问题请在评论中提出。
祝你好运!

它能工作,非常感谢。这是一个错误还是不是?为什么我只在第一次使用getSupportedFragmentManager时才能工作,第二次就不行了。 - Eagle
你正在一个Fragment中使用另一个Fragment,在这种情况下,你必须使用父Fragment的FragmentManager而不是Activity的。 - mmlooloo
2
我爱你,伙计。这个问题让我苦恼了很久,我已经无聊地花了两天时间希望解决这个问题。getChildFragmentManager 这一小段代码真的救了我的一天,谢谢兄弟。祝你好运 ;) - Biskrem Muhammad
救了我的一天! - Sharique Abdullah
这对我非常有效!谢谢你!你省了我很多麻烦。 - sourlemonaid

3
在你的Fragment类中,在onCreate()方法中,你需要像这样调用setRetainInstance(true):
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);     
    setRetainInstance(true);
}

这将告诉FragmentManager在重新加载时保留您的片段。 此外,请检查您的清单文件是否有任何

android:screenOrientation

配置更改是指您将自行处理由于配置更改而导致的重新加载。

2
在 PagerFragment 的 onResume() 方法中添加以下内容:
@Override
public void onResume() {
    super.onResume();

    for (Fragment fragment : getFragmentManager().getFragments()) {
        if (fragment instanceof Tab1Fragment || fragment instanceof Tab2Fragment) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.detach(fragment);
            ft.attach(fragment);
            ft.commit();
        }
    }
}

这段代码为什么必要,如果能解释一下会更好。 - Woodrow Barlow
对于我的场景,我正在使用底部导航(bottomNavGroup),其中包含两个片段。在其中一个片段上,我有一个viewpager,它显示3个其他子片段。从您的答案中解决了我的问题,但我不知道为什么首先会出现这种情况,有人有想法请回复? - Arul

1
确保将适配器实例传递给子片段管理器,而不是片段管理器。
像这样: this._adapter = new PagerAdapter(getChildFragmentManager());

1
尝试在您的代码中添加以下行:

public int getItemPosition(Object object) {
   return POSITION_NONE;
}

并添加以下行。
pager.setOnPageChangeListener(new OnPageChangeListener() {
     @Override
     public void onPageSelected(int position) {
          ... anything you may need to do to handle pager state ...
          adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
     }

Under

pager.setAdapter(adapter);

希望这可以帮到你!

你已经添加了 adapter.notifyDataSetChanged(); 吗? - Krupa Patel
添加了以下代码到 PagerAdapter:@Override public int getItemPosition(Object object) { return POSITION_NONE; } - Eagle
this._adapter.notifyDataSetChanged(); - Krupa Patel
HomeFragment public void onPageSelected(int i) { HomeFragment.this._adapter.notifyDataSetChanged(); } - Eagle
onPageSelected 没有触发 - Eagle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接