web-dev-qa-db-ja.com

Viewpager2を持つキーFragmentStateAdapterのフラグメントは存在しません

プロジェクトにViewPager2を使用しています。 viewpager2でフラグメント内にネストされたフラグメントを使用する必要があります。初めてフラグメント(ネストされたフラグメントではない)間を移動しようとするまで、それは魅力のように機能します。

ネストされたフラグメントを含むフラグメントOnCreateViewメソッド:

View view = inflater.inflate(R.layout.orders_fragment, null);

ViewPager2 viewPager = view.findViewById(R.id.childViewPager);

TabLayout tabs = view.findViewById(R.id.tabs);

SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(),getLifecycle());

viewPager.setAdapter(sectionsPagerAdapter);

TabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy = (tab, position) -> {

    String[] order_activity_tabs = getResources().getStringArray(R.array.situations);

    for (int i=0; i<order_activity_tabs.length; i++) {

        if(i==position)
            tab.setText(order_activity_tabs[i]);

    }
};

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabs, viewPager, tabConfigurationStrategy);
tabLayoutMediator.attach();

return view;

ネストされたフラグメントを含むフラグメントを返すと、クラッシュします

 Java.lang.IllegalStateException: Fragment no longer exists for key f#0: unique id 4fbe17b8-5e22-4e07-a543-4a79445ad39c
        at androidx.fragment.app.FragmentManagerImpl.getFragment(FragmentManagerImpl.Java:365)
        at androidx.viewpager2.adapter.FragmentStateAdapter.restoreState(FragmentStateAdapter.Java:549)
        at androidx.viewpager2.widget.ViewPager2.restorePendingState(ViewPager2.Java:350)
        at androidx.viewpager2.widget.ViewPager2.dispatchRestoreInstanceState(ViewPager2.Java:375)
        at Android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.Java:4045)
        at Android.view.View.restoreHierarchyState(View.Java:20253)
        at androidx.fragment.app.Fragment.restoreViewState(Fragment.Java:548)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.Java:907)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.Java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.Java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.Java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.Java:2079)

FragmentStatePagerAdapterにはソリューションがありますが、FragmentStateAdapterにはありません。また、FragmentStateAdapterのメソッドをオーバーライドできないため、このソリューションの実装は不可能です。

これを読んでいただきありがとうございます。どんな助けでもありがたいです。

3
Eren Tüfekçi

FragmentStateAdapterでviewpager2を使用すると、FragmentStatePagerAdapterと同様の動作になります。

実際、この問題を解決するには2つの方法があります

まず、viewpager2にsetSaveEnabled()をfalseに設定します

viewpager2.setSaveEnabled(false)

もう1つはアダプタでrestoreStateをオーバーライドしてnullを返します

チェック: https://developer.Android.com/reference/androidx/viewpager2/adapter/FragmentStateAdapter

3

新しいナビゲーションコンポーネントの実装で私の問題は解決しました。それ自体がフラグメント遷移を処理します。この問題に遭遇した人は誰でもナビゲーション方法を変更できます。

0
Eren Tüfekçi

私は同じ問題を抱えていました。原因は、含まれているフラグメントが再作成されるときに、そのchildFragmentManagerも同様であることです。そして、FragmentStateAdapterは渡されたフラグメントマネージャーを調べて、状態を復元するフラグメントを見つけます。

私の解決策は、フラグメントではなくアクティビティのfragmentManagerを使用することでした。たとえば、次のようなアクティビティを取得するコンストラクタを使用します。

class MyAdapter(f: Fragment) : FragmentStateAdapter(f.activity!!)
0
allanman