簡體   English   中英

導航回 FragmentPagerAdapter -> 片段為空

[英]Navigating back to FragmentPagerAdapter -> fragments are empty

我有一個 Fragment(我稱之為pagerFragment ),它被添加到 backstack 並且是可見的。 它擁有一個帶有FragmentPagerAdapterviewPager FragmentPagerAdapter包含(假設)兩個片段:A 和 B。

首先添加片段效果很好。

片段 A 有一個按鈕,單擊該按鈕后,會將片段 (C) 添加到 backstack。

問題是這樣的:如果我添加那個片段(C),然后點擊返回, pagerAdapter是空的,我看不到里面的任何片段。

如果我使用 hack 並銷毀pagerFragment s onDestroyView()的子片段(A 和 B onDestroyView() ,這可以解決問題,盡管我不想使用此 hack。

任何想法可能是什么問題?

我有同樣的問題。 我的解決方案很簡單:

在 onCreateView 我有:

// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity()
    .getSupportFragmentManager());

其中 SectionPageAdapter 是這樣的:

class SectionsPagerAdapter extends FragmentPagerAdapter {
...
}

將 getSupportFragmentManager 更改為

mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());

它開始工作了! 希望這可以幫助。

聽起來您正在使用嵌套片段,因為您的 ViewPager 位於 PagerFragment 內。 您是否已將 getChildFragmentManager() 傳遞給 FragmentPagerAdapter 的構造函數? 如果不是,你應該。

我認為您不需要 FragmentStatePagerAdapter,但我會嘗試一下,因為它可以處理保存和恢復 Fragment 狀態。 您的 onDestroyView() hack 有效這一事實讓我認為您可能需要 FragmentStatePagerAdapter。

它還可能與 FragmentPagerAdapter 添加 Fragments 的方式有關。 FragmentPagerAdapter 不會將 Fragments 添加到 backstack。 想象一下,如果您在 ViewPager 中添加了 10 多個頁面並且用戶在它們之間滑動。 用戶需要回擊 11 次才能退出應用程序。

也可能與這篇文章有關: Nested Fragments and The Back Stack

另外,我不確定您要將片段 C 添加到什么中。 您是否將其添加到與 ViewPager 相同的容器中?

好吧,至少你有幾個選擇來調查。 在這些情況下,我喜歡調試到 Android SDK 源代碼中,看看是什么導致了這種行為。 我建議獲取AOSP 源並添加 frameworks/support 和 frameworks/base 作為您的 SDK 源。 這是了解正在發生的事情並避免在一切正常之前進行隨機更改的唯一正確方法。

使用getChildFragmentManager()而不是getSupportFragmentManager() 它會正常工作。

我剛剛在我們的項目中也遇到了這個問題。 根本原因是 FragmentPagerAdapter 的工作方式:

FragmentPagerAdapter 只是將他當前不需要的 Fragment 從其 View 中分離,但不會將其從其 FragmentManager 中移除。 當他想再次顯示 Fragment 時,他會使用從 ViewPager 的視圖 ID 和適配器 getItemId(position) 調用返回的 ID 創建的標記來查看 FragmentManager 是否仍包含 Fragment。 如果他找到一個 Fragment,他只需在 FragmentManager 的更新事務中安排將 Fragment 附加到其視圖。 只有當他沒有以這種方式找到 Fragment 時,他才會使用適配器 getItem(position) 調用創建一個新的 Fragment!

包含帶有 FragmentPagerAdapter 的 ViewPager 的 Fragment 的問題是,當包含的 Fragment 被放入后堆棧時,永遠不會清除 FragmentManager 的內容。 如果包含 Fragment 從返回堆棧返回,它會創建一個新視圖,但 FragmentManager 仍然包含附加到舊視圖的片段,並且現有片段的附加不再起作用。

擺脫這個問題的最簡單方法是避免嵌套片段。 :)

第二種最簡單的方法是在其他帖子中已經提到,將 ChildFragmentManager 用於 FragmentPagerAdapter,因為這個方法在容器片段的生命周期中得到正確更新。

由於有些項目(作為我當前的項目)無法使用這兩個選項,因此我在此處發布了一個解決方案,該解決方案可與任意 FragmentManager 一起使用,方法是使用子片段的 hashCode 作為該位置片段的項目 ID。 它的代價是存儲適配器內所有位置的所有片段。

public class MyPagerAdapter extends FragmentPagerAdapter {

private static int COUNT = ...;
private final FragmentManager fragmentManager;
private Fragment[] subFragments = new Fragment[COUNT];
private FragmentTransaction cleanupTransaction;

public MyPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
    this.fragmentManager = fragmentManager;
}

@Override
public Fragment getItem(int position) {
    return getSubFragmentAtPosition(position);
}

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

@Override
public long getItemId(int position) {
    return getSubFragmentAtPosition(position).hashCode();
}

//The next three methods are needed to remove fragments no longer used from the fragment manager
@Override
public void startUpdate(ViewGroup container) {
    super.startUpdate(container);
    cleanupTransaction = fragmentManager.beginTransaction();
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    cleanupTransaction.remove((Fragment) object);
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
    cleanupTransaction.commit();
}

private Fragment getSubFragmentAtPosition(int position){
    if (subFragments[position] == null){
        subFragments[position] = ...;
    }
    return subFragments[position];
}

}

我有同樣的問題,只需一次設置適配器兩次僅此而已。

示例代碼:

 private fun displayImg(photo1:String, photo2:String){ val pager:ViewPager = v?.findViewById(R.id.ProductImgPager)!! val arr = ArrayList<String>() arr.add(photo1) arr.add(photo2) pager.adapter = AdapterImageView(fm, arr ,arr.size) pager.adapter = AdapterImageView(fm, arr ,arr.size) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM