web-dev-qa-db-ja.com

画面の回転を変更すると、ViewPagerフラグメントが消える

私はAndroid ViewPagerFragmentsを含むアプリケーションに取り組んでいます、次のように:

MainActivityMainActivityFragmentscreenSlideViewPagerFragments)))、つまり、

ActivitycontainsFragmentcontainsViewPagercontainsFragments

今私の問題は、デバイスの回転または画面の回転を変更すると、ViewPagerのすべてのフラグメントが表示されなくなることです。

この問題を解決するためのアイデアはありますか?

編集1

MainActivity.Java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getSupportFragmentManager().findFragmentByTag(TAG) == null) {
        final FragmentTransaction ft = getSupportFragmentManager()
                .beginTransaction();
        ft.add(Android.R.id.content, new MainActivityFragment(), TAG);
        ft.commit();
    }
}

MainActivityFragment.Java:

public class MainActivityFragment extends Fragment {
    private ViewPager mPager = null;
    private PagerAdapter mPageAdapter = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View reVal = inflater.inflate(R.layout.activity_main, container, false);
        mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
        mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());
        mPager.setAdapter(mPageAdapter);
        return reVal;
    }

    private MainGridViewFragment mainGridFragment;
    private AlphabetGridViewFragment alphabetGridFragment;

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Android.app.Fragment getItem(int position) {
            switch (position) {
                case 1:
                    mainGridFragment = new MainGridViewFragment();
                    return mainGridFragment;
                case 0:
                    alphabetGridFragment = new AlphabetGridViewFragment();
                    return alphabetGridFragment;
                default:
                    return null;
            }
        }

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

編集2 The Activity After Screen Rotation

明らかにMainActivityMainActivityFragmentが読み込まれ、証明はActionBarです。また、ページ間を移動できるため、ViewPagerも読み込まれていることに注意してください(青色のライトは、ページャーが最後のページに到達したことを意味しますが、その内容を見ることができません。

31
Heysem Katibi

フラグメントがgetFragmentManager()を使用している間、メインアクティビティはgetSupportFragmentManager()を使用しているようです。

これが回答投稿に値するかどうかはわかりませんが、私の評価は他の方法で返信するには低すぎます。 :)

編集:サポートライブラリでFragmentActivityを拡張する必要があるかもしれません。

参照: https://stackoverflow.com/a/10609839/264069

編集2:

public class MainActivityFragment extends FragmentActivity {
    private ViewPager mPager = null;
    private PagerAdapter mPageAdapter = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View reVal = inflater.inflate(R.layout.activity_main, container, false);
        mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
        mPageAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
        mPager.setAdapter(mPageAdapter);
        return reVal;
    }

    private MainGridViewFragment mainGridFragment;
    private AlphabetGridViewFragment alphabetGridFragment;

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 1:
                    mainGridFragment = new MainGridViewFragment();
                    return (Fragment)mainGridFragment;
                case 0:
                    alphabetGridFragment = new AlphabetGridViewFragment();
                    return (Fragment)alphabetGridFragment;
                default:
                    return null;
            }
        }

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

私は多くの解決策を試しましたが、どれでも成功しました。ついに私は以下のように修正しました:

  • GetChildFragmentManager()ではなくgetActivity()。getSupportFragmentManager()を使用します

  • 以下のように、ViewPagerAdapterクラスのgetItemId(int position)メソッドをオーバーライドします。

    @Override
    public long getItemId(int position) {
        return System.currentTimeMillis();
    }
    

私にとってそれは魅力のように働いています、あなたの意見もここにコメントしてください。

5
Kalpesh

これで問題を抱えている人のために、これを試すことができます:

private void InitializeUI(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.activity_exame2);
InitializeUI();
}

私はこの問題の周りに2日間費やしました。これが私に有効な唯一のことでした。Android:configChanges = "screenSize | orientation"をマニフェストのアクティビティに追加することを覚えておいてください

3
Tiago Oliveira

私はこれとまったく同じ問題を抱えていました。途方もなく混乱しますが、このスレッドは私を助けました。

この問題を修正するには、Fragment.getChildFragmentManager()を使用します。 Android APIにはActivity.getFragmentManager()がありますが、古いデバイスをサポートする場合はActivity.getSupportFragmentManager()を使用する必要があります。ただし、この特定の問題は混乱を招きます。古いAPIのサポートについてではありません。

問題は、いくつかのフラグメントを所有するViewPagerを所有するフラグメントを持つアクティビティがあることです。フラグメント内にフラグメントがあります! Fragmentsの元のデザインはこのユースケースを実際には処理しませんでしたが、後でそれを処理するように更新されました。 Fragments内にFragmentsがある場合、使用する必要があります。

Fragment.getChildFragmentManager()

Fragment内からFragmentManagerActivityを返すFragment.getFragmentManager()と、このFragmentManagerFragmentを返すFragmentFragment_内に適切にスコープするFragment.getChildFragmentManager()を選択できます。

3
chubbsondubs

私の場合、フラグメントF1を持つアクティビティAがあり、ビューページャーV1を持つフラグメントには、フラグメントF3を持つビューページャーV2を持つフラグメントF2があります。 :)

この最後のフラグメントF3を回転すると、空白またはエラーが発生します。

私の解決策は:

  1. PageChangeListenerを削除します。基本的に、フラグメントを変更するときにフラグメントトランザクションを使用せず、デフォルトのままにします。
  2. FragmentPagerAdapterの代わりにFragmentStatePagerAdapterを使用してください
  3. アダプターのgetItemPosition()をオーバーライドし、POSITION_NONEを返します
  4. アダプターにフラグメントのリストを含むフィールドを作成し、コンストラクターに設定します
  5. アダプタのgetItem()では、fragmentList.get(position)を返すだけです
  6. アダプターのgetCount()では、単にfragmentList.size()を返します
  7. Destroy、instantiateなど、アダプターの他のメソッドをオーバーライドしないでください。
  8. F2のonCreateView()でV2アダプターを作成してインスタンス化する

[〜#〜]編集[〜#〜]

たとえば、F1のV1をF2のV2に置き換える必要がある場合:

  1. V1をF1_container idで相対レイアウトの内側に囲む
  2. GetSupportFragmentManager()を使用してトランザクションを開始します
  3. F1を削除
  4. F1_containerをF2に置き換えます
  5. バックスタックに追加
  6. トランザクションをコミットする

後でF2からF1に戻る必要がある場合、有効なA参照でpopBackStack()を呼び出します。

それを考えてみてください。それぞれを変更してアプリを再起動し、結果を確認するのに1日以上かかりました。お役に立てれば。

1
10101101

getChildFragmentManager()の代わりにgetFragmentManager()を使用する必要があります。使いました

mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());

それはあったはずです

mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getChildFragmentManager());

あなたの断片で

1
Fatimehin Dare

再度ビューページャーを作成しないでください。 onCreateViewのコードをonCreate()に配置します。そして、フラグメントでonRetainInstance(true)を使用します。したがって、これはフラグメントを再作成しません。また、ビューがonCreate()にあるため、再度呼び出されることはありません。

OnCreateView()でビューが存在するかどうかを確認し、存在する場合は削除します。切れ端:

//creates the view
private View createView(Bundle savedInstanceState) {
    View view = getActivity().getLayoutInflater().inflate(your_layout, null, false);

    //viewpager

    return view;
}

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

    //retains fragment instance across Activity re-creation
    setRetainInstance(true);

    viewRoot = createView(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    if (viewRoot != null && viewRoot.getParent() != null) {
        ViewGroup parent = (ViewGroup) viewRoot.getParent();
        parent.removeView(viewRoot);

        Log.i("Test", "**************view.getParent(): " + viewRoot.getParent() + "    " + viewRoot);
    }

    return viewRoot;
}
1