23

FragmentPagerAdapter と一緒に ViewPager を使用して、3 つの異なるフラグメントをホストしています

[Fragment1][Fragment2][Fragment3]

私が達成しようとしているのは、特定のタスクが成功した場合に、Fragment1 をまったく新しいフラグメント Fragment4 に正常に置き換えることです。

使うと..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, fragment4);
transaction.commit();

..フラグメントがきれいに置き換えられ、Fragment1 の代わりに Fragment4 が表示されます。Fragment3 までスワイプしてから Fragment4 に戻るとすぐに、Fragment1 が復活しました。

それからもう一度、私が使用すると..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment1);
transaction.commit();

..Fragment1 が削除され、戻ってくると Fragment4 があります。したがって、このソリューションの問題は、Fragment1 が削除されたときに Fragment4 をすぐに表示する方法を見つけられなかったことです。

transaction.add(fragment4);
transaction.show(fragment4);

そして、トランザクション管理なしで、現時点で FragmentPagerAdapter 実装がどのように見えるかを次に示します。

public static class PagerAdapter extends FragmentPagerAdapter {

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

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

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = null;

        switch (position) {
        case 0:
            fragment = Fragment1.newInstance(context_);
            break;

        case 1:
            fragment = Fragment2.newInstance(context_);
            break;

        case 2:
            fragment = Fragment3.newInstance(context_);
            break;

        default:
            break;
        }

        return fragment;
    }
}

編集。

そのため、質問が完全に明確ではなかったようです。以前に作成できたスパゲッティをすべて削除することにし、それらを省略したことを述べようとしました (上記の太字のテキストを参照)。

とにかく、これは私が getItem() 内でやろうとしてきたことのほとんどです:

@Override
public Fragment getItem(int position) {

    Fragment fragment = null;

    switch (position) {
    case 0:

        if (!app.isUserLoggedIn) {
            if (loginFragment_ == null) {
                loginFragment_ = LoginFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (logoutFragment_ != null) {
                    transaction_.remove(logoutFragment_);
                    logoutFragment_ = null;
                }

                transaction_.add(loginFragment_, "login");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("login") == null)
                fragment = LoginFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("login");

        } else {
            if (logoutFragment_ == null) {                      
                logoutFragment_ = LogoutFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (loginFragment_ != null) {
                    transaction_.remove(loginFragment_);
                    loginFragment_ = null;
                }

                transaction_.add(logoutFragment_, "logout");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("logout") == null)
                fragment = LogoutFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("logout");
        }
        break;

    case 1:
        fragment = HomeFragment.newInstance(context_);
        break;

    case 2:
        fragment = RegisterFragment.newInstance(context_);
        break;

    default:
        break;
    }

    return fragment;
}

このコードでは何もできませんが、誰かが私が間違っていることを見て、正しい方向に向けたいと思ったら、とても感謝しています!

4

5 に答える 5

12

FragmentStatePagerAdapter を使用してみてください

http://android-developers.blogspot.com/2011_08_01_archive.html

ビューをスワイプすると(getitemを呼び出すときも)フラグメントが削除されるため、自分で明示的に削除する必要はありません。

私はそれが私のために働くのと同じ問題を抱えていました。

あなたのコードを試してif (fragment!=null)ブロックを削除すると、うまくいきます。

于 2011-09-26T08:00:03.853 に答える
3

Maurycy が言っmAdapter.notifyDataSetChanged()たように、フラグメントが置き換えられたことを ViewPager に伝えたいときはいつでも呼び出す必要があります。getItemPosition()ただし、アダプターの抽象関数をオーバーライドし、古い非表示のフラグメントを引数として呼び出したときに POSITION_NONE を返す必要もあります。それ以外の場合、ViewPager は現在のすべてのフラグメントを保持します。

詳細とコード例については、関連する質問に対するこの回答を参照してください。

于 2012-02-03T11:58:30.480 に答える
0

FragmentPagerAdapter 内の List を使用してさまざまなフラグメントを処理することで、この問題を解決しました。

    public void addScreen(String tag, Class<?> clss, Bundle args){
        if(clss!=null){
            TabInfo info = new TabInfo(tag, clss, args);
            screens.add(info);
        }
    }
@Override
    public Fragment getItem(int position) {
        TabInfo info = screens.get(position);
        return Fragment.instantiate(context, info.clss.getName(), info.args);
    }

次に、プログラムでリスト項目 (フラグメント) を削除/追加/再配置し、ハンドラーを呼び出します

mAdapter.notifyDataSetChanged()
于 2012-01-28T01:33:39.980 に答える
0

getItem状況によっては、ステートメントが fragment4 を返すべきではありませんcase 0か?

于 2011-09-16T14:32:34.427 に答える
0

offScreenPageLimit を 5 (またはユースケースに基づいて) に設定して、フラグメントのリロードを回避し、スワイプ時にリロードされるのではなく、置き換えたものが残るようにしてください。

    mViewPager.setOffscreenPageLimit(5);
于 2018-02-22T14:33:54.867 に答える