11

ViewPager + FragmentPageAdapter に問題があります。

シナリオ: フラグメント A 内に 1 つのアクティビティがあります。フラグメント A には、フラグメント B1 とフラグメント B2 を含む ViewPager があります。B1 e B2 は同じクラスですが、引数としてのデータが異なります。

問題: 作成時にすべてが正常に機能します。しかし、アプリがバックグラウンドになり、プロセスがアンドロイドによって強制終了され、最後の状態を復元しようとしてアプリを再び起動すると、フラグメント B1 e B2 はフォアグラウンドで表示されませんが、フラグメント A は表示されます。少し奇妙に思えるのは、フラグメント B1 と B2 がフラグメント A の ChildFragmentManager の int であり、onStart() と onResume() が呼び出されたために再開されることです (ログで確認できます)。さらに、ページャーは 2 ページで再開されますが、何も表示されずに空かそれ以上の状態になります。

FragmentPagerAdapter がどのように機能するかをよく理解していれば、独自のフラグメントとそれらを再作成する方法を管理するのはその責任です。さらに、この点を強制するために、FragmentPagerAdapter は、指定されたタグを持つその位置にフラグメントが既に存在する場合、バックグラウンドから戻ったときに getItem(int position) を呼び出しません。

...では、Fragment B1 e B2 が表示されず、Pager が空である理由は何ですか?

これは私のサンプルコードです。

フラグメントA

@Override
    public void onStart() {
        super.onStart();
        populateViewPager();
    }

    private void populateViewPager() {
        pager.setAdapter(new MyFragmentPageAdapter(getChildFragmentManager()));
        indicator.setViewPager(pager);
        indicator.notifyDataSetChanged();
    }

FragmentPagerAdapter

public class MyFragmentPageAdapter extends FragmentPagerAdapter {


    public MyFragmentPageAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return FragmentB.newInstance(position);
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        String title = "";
        if (position == 0)
            title = "Fragment B1";
        else if (position == 1)
            title = "Fragment B2";

        return title;
    }
}

フラグメント B

        public static FragmentB newInstance(int position) {
                FragmentB f = new FragmentB();
                Bundle b = new Bundle();
                b.putInt(POSITION_IN_PAGER_ARGUMENT, position);
                f.setArguments(b);
                return f;
            }

            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                Log.d(TAG, "onCreate");
            }

            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                super.onCreateView(inflater, container, savedInstanceState);
                Log.d(TAG, "onCreateView");
                View root = inflater.inflate(R.layout.fragment_b_layout, container, false);

                empty = (TextView) root.findViewById(R.id.empty);
                list = (ListView) root.findViewById(R.id.list);

                return root;
            }

            @Override
            public void onStart() {
                super.onStart();
                Log.d(TAG, "onStart");
                populateListView(loadData());

            }

            @Override
            public void onStop() {
                super.onStop();
            }
    }
4

2 に答える 2

8

FragmentPagerAdapter の代わりに FragmentStatePagerAdapter を使用します。それは私のために働いた。ただし、ViewPager に表示するビューが多数ある場合は、メモリの問題が発生します (画面の向きが変更されている間のみ)。

于 2013-10-28T09:36:42.143 に答える
0

これがタブ付きの私の PagerDadapter です。少し役立つかもしれません。

public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context               mContext;
        private final ActionBar             mActionBar;
        private final ViewPager             mViewPager;
        private final ArrayList<TabInfo>    mTabs   = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?>  clss;
            private final Bundle    args;

            TabInfo(Class<?> _class, Bundle _args) {

                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {

            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getSupportActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

        /**
         * methode qui construit un onglet
         * 
         * @param tab
         * @param clss
         * @param args
         */
        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {

            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {

            return mTabs.size();
        }

        @Override
        public Fragment getItem(int position) {

            TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        public void onPageSelected(int position) {

            mActionBar.setSelectedNavigationItem(position);
            ((SherlockFragmentActivity) mContext).supportInvalidateOptionsMenu();
        }

        public void onPageScrollStateChanged(int state) {

        }

        public void onTabSelected(Tab tab, FragmentTransaction ft) {

            //
            // force l'appel de onOptionMenuPrepared
            ((SherlockFragmentActivity) mContext).supportInvalidateOptionsMenu();
            Object tag = tab.getTag();
            for (int i = 0; i < mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }

        public void onTabUnselected(Tab tab, FragmentTransaction ft) {

        }

        public void onTabReselected(Tab tab, FragmentTransaction ft) {

        }
    }
于 2013-07-05T12:34:48.410 に答える