24

この例を使用して FragmentStatePagerAdapter を使用しています。

MyAdapter クラスは次のように実装されます。

public static class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

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

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

ListFragment クラスには、新しいインスタンスを作成する次のメソッドが含まれています。

    /**
     * Create a new instance of CountingFragment, providing "num"
     * as an argument.
     */
    static ArrayListFragment newInstance(int num) {
        ArrayListFragment f = new ArrayListFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }

アクティビティで新しいフラグメント状態ページャー アダプターを作成すると、getItemが呼び出さnewInstanceれ、ListFragment クラスのメソッドが呼び出されます。これは、新しいフラグメントを作成したいときに最適です。

しかし、フラグメントオブジェクトが既に存在する場合にフラグメントオブジェクトを取得し、たとえばページ 2 からページ 1 へのユーザーページgetItemを取得するために (必要な場合でも)変更する方法は明確ではありません。フラグメント クラスに存在する内部クラスを実行できるようにフラグメントを作成しました。AsyncMethod

4

6 に答える 6

44

解決策は、提供された回答よりもはるかに簡単だと思います。

のソースをFragmentStatePagerAdapter.instantiateItem()見ると、instantiateItem()がこのロジックを処理するため、 の実装はgetItem()常に新しいインスタンスを返す必要があることに気付くでしょう。

したがって、既存の Fragment を返すには、次のようにします (から呼び出していると仮定しますViewPager):

Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem());
于 2013-10-06T14:52:29.760 に答える
9

@imiric の解決策は非常に簡潔ですが、それでもクラスの実装に関する知識が必要であることが気になります。私の解決策は、フラグメントを破壊する可能性のある FragmentStatePagerAdapter で適切に動作するはずのアダプターに以下を追加することです。

    private SparseArray<WeakReference<Fragment>> mFragments = new SparseArray<>();

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment f = (Fragment) super.instantiateItem(container, position);
        mFragments.put(position, new WeakReference<>(f));  // Remember what fragment was in position
        return f;
    }

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

    public Fragment getFragment(int position) {
        WeakReference<Fragment> ref = mFragments.get(position);
        Fragment f = ref != null ? ref.get() : null;
        if (f == null) {
            Log.d(TAG, "fragment for " + position + " is null!");
        }
        return f;
    }
于 2014-05-02T11:36:26.530 に答える
6

私はあなたが持っているものに似たものを実装しました。FragmentPagerAdapter私はクラスを次のように拡張しました:

public class ContactsFragmentPagerAdapter extends FragmentPagerAdapter {
    ActionBar mActionBar;
    private List<Fragment> mFragments;

    public ContactsFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        mFragments = fragments;
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

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

    public void setActionBar(ActionBar bar) {
        mActionBar = bar;
    }
}

オブジェクトのListに渡す引数をコンストラクターに追加したことに注意してください。FragmentこのようにしてgetItem()、このクラスのメソッドは、あなたが行ったような特定のクラスだけでなく、拡張するクラスFragmentまたはそのサブクラスのいずれかを返すことができArrayListFragmentます。

Activityサブクラスをインスタンス化する場所で、オブジェクトFragmentPagerAdapterのリストを渡しました。Fragment

FragmentPagerAdapter をインスタンス化するクラス

public final class ContactManager extends Activity {
    private ContactsFragmentPagerAdapter mAdapter;
    private ViewPager mPager;
    public ActionBar mActionBar;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.contact_manager);

        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, ContactsListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, GroupsListFragment.class.getName()));
        mAdapter = new ContactsFragmentPagerAdapter(this.getFragmentManager(), fragments);

        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

        mPager.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrollStateChanged(int arg0) {}

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {}

            @Override
            public void onPageSelected(int arg0) {
                mActionBar.getTabAt(arg0).select();
            }
        });

    }

}

変数「fragments」にアクセスすることで、以前に作成Fragmentした にアクセスして、その のメソッドを実行できますFragment

于 2012-10-24T20:45:39.510 に答える
4
public class MyPagerAdapter extends FragmentStatePagerAdapter {
    final Context m_context;
    final WeakReference<Fragment>[] m_fragments;

    public DetailPagerAdapter(FragmentManager fm) {
        super(fm);
        m_context = ...
                m_fragments = new WeakReference[enter size here];
    }

    @Override
    public Fragment getItem(int position) {
        final Fragment fragment = instantiate your fragment;
        m_fragments[position] = new WeakReference<Fragment>(fragment);
        return fragment;
    }

    @Override
    public int getCount() {
        return ...
    }

    public Fragment getFragment(final int position) {
        return m_fragments[position] == null ? null :
            m_fragments[position].get();
    }
}
于 2013-03-12T19:13:28.433 に答える