フラグメントは置き換えられていませんが、前のものの上に置かれています


104

アクティビティ:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();

transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();

FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();

ビューのコード:

<fragment
    android:id="@+id/Fragment1"
    android:name="com.landa.fragment.Fragment1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/include1" /> 

問題は、コンテンツが実際に置き換えられないことです。つまり、コンテンツが上に配置されます(そのため、コンテンツはオーバーラップします)。

クリックすると、最初のフラグメントは適切に(2番目のフラグメントなしで)表示されますが、最初は両方が表示されています(最後のフラグメントのみを表示したい)。

ここで何が欠けていますか?


私の場合、問題は、コンテナビューの適切なIDを使用していない、つまりcontainerViewIdreplaceメソッドで)正しい値を渡していないという事実によるものでした。
nbro、

回答:


145

ここで2つの間違ったことが行われています。

  1. xmlレイアウトファイルに静的に配置されたフラグメントを置き換えることはできません。FrameLayoutレイアウトにコンテナ(例:a )を作成し、を使用してプログラムでフラグメントを追加する必要がありますFragmentTransaction

  2. FragmentTransaction.replace最初のパラメーターとして、フラグメントのIDではなく、フラグメントを含むコンテナーのIDが必要です。したがって、最初のフラグメントを追加したコンテナのIDとして最初の引数を渡す必要があります。

詳細については、このリンクを参照してください。


17
FrameLayoutコンテナとして使用するのは、を使用するよりも優れていLinearLayoutます。
Marcel Bro

3
Activityで空のFrameLayoutを使用すると、私の問題も解決されました
微妙なFox

1
これはうまくいきます。しかし、アプリケーションを起動してすぐに戻るボタンを押すと、アプリケーションを終了するのではなく、フラグメントが空の状態になりますか?
MasterScrat 2017

@MasterScrat addTobackStack(..)初めてトランザクションを行うときは省略します。これにより、空のFrameLayoutコンテナがバックスタックに配置されるのを回避できます。追加したフラグメントに戻ることができます。
Alex Meuer 2017

ここにあなたの説明を示す素晴らしいビデオがあります。youtube.com/watch?v=EbcdMxAIr54
SQLおよびJava学習者

32

同様の問題がありましたが、私の問題は、2つの異なるフラグメントマネージャーを使用getSupportFragmentManager()していたことgetFragmentManager()です。で1つのフラグメントを追加してSupportFragmentManagerから、そのフラグメントをで置き換えようとするFragmentManagerと、フラグメントが上に追加されます。同じコードFragmentManagerが使用され、問題が解決されるようにコードを変更する必要がありました。


17

Android開発者サイトでは、を使用FrameLayoutして実行時にフラグメントを動的にロードすることを推奨しています。フラグメントをxmlファイルにハードコーディングしました。したがって、このリンクで言及されているように、実行時に削除することはできません。

http://developer.android.com/training/basics/fragments/creating.html

このリンクは、プログラムを通じてフラグメントを追加する方法を示しています。

http://developer.android.com/training/basics/fragments/fragment-ui.html


7

私は同じ問題を抱えてすべての答えを見ましたが、どれも私の間違いを含んでいませんでした!現在のフラグメントを置き換える前に、次のようにコンテナーアクティビティのxmlにデフォルトのフラグメントを表示していました。

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="....ShopFragment"
        android:id="@+id/fragment"
        tools:layout="@layout/fragment_shop" />
</FrameLayout>

その後、私はをに渡していFrameLayoutましたfragmentTransaction.replace()が、正確な問題がありました。前のフラグメントの上に2番目のフラグメントが表示されていました。

次のように、xmlからフラグメントを削除し、プログラムonCreate()の開始時にデフォルトプレビューのコンテナーアクティビティのメソッドでプログラムによってそれを表示することにより、問題が修正されました。

    fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment());
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

コンテナアクティビティxml:

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

4

フラグメントを置き換える前に、backStackをクリアできます。

    FragmentManager fm = getActivity().getSupportFragmentManager();

    for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
        fm.popBackStack();
    }

    // replace your fragments

問題は、XMLレイアウトファイルでフラグメントを宣言していることです。したがって、実行時に削除または置換することはできません。
Poonam Anthony 2013

これは私にとってはうまくいき、バックスタックをクリアせずにフラグメントを置換しようとすると、他のフラグメントの上に最新のバックスタックエントリが残っているように見えました。
speedynomads 14年

3
<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:windowBackground">
//Add fragment here
</FrameLayout>

android:background="?android:windowBackground">フラグメントが存在するコンテナに追加します。私の場合、私はを追加しましたFrameLayout、それは役立つはずです。


1

フラグメントを使用する代わりにコンテナを使用する

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hello World!" />

MainActivityになりました

if(condition)
    getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();                    
else
    getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();

フラグメントクラスは「android.app.Fragment」をインポートする必要があることに注意してください。「support.v4」または「元の」実装を使用し、それらを混在させないようにしてください。私はそれらを混ぜていたので、私はこの問題を抱えていました。


0

Sapan Diwakarの回答に同意します。しかし、私はこれを行う方法についての回避策を見つけました。

まず、activity_mainすべてのレイアウトがあるアクティビティ(例:)で、を追加しFrameLayoutます。高さと幅はでなければなりませんmatch parent。また、それを与えるidます。

次に、現在のレイアウトを置き換えるフラグメントで、onPause()およびを呼び出しますonResume()。のすべての内部コンテナを初期化しViewます。そして、彼らのセットvisibilityにするGONEonResume()してVISIBLEonPause()

FrameLayoutこのフラグメントで置き換えるものではありません。

あなたが持っていると仮定しViewPagerTabLayoutImageViewおよびカスタム<fragment>の中でactivity_main.xmlFrameLayout上記のa を追加します。

abcFragment.javaonClick()機能追加addToBackstack(null)transaction

コード例:

abcFragment(およびactivity_main.xmlに表示されているすべてのもの)を置き換えるxyzFragmentで、次のようにします。

@Override
    public void onResume() {
        super.onResume();

    // On resume, make everything in activity_main invisible except this fragment.
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.GONE);
    viewPager.setVisibility(View.GONE);
    miniPlayerFragment.setVisibility(View.GONE);
}

@Override
public void onPause() {
    super.onPause();

    // Make everything visible again
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.VISIBLE);
    viewPager.setVisibility(View.VISIBLE);
    miniPlayerFragment.setVisibility(View.VISIBLE);
}

幸せなコーディング!


0

FragmentTransactionのsetTransitionメソッドを使用して、重複する問題を修正できます。

transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

0

Oncreate()内

  BaseFragmentloginpage fragment = new BaseFragmentloginpage();
            android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.frame, fragment);
            fragmentTransaction.isAddToBackStackAllowed();
            fragmentTransaction.commit();

これは常にデフォルトのフラグメントになります... xmlレイアウトでフラグメントを追加すると、常にオーバーラップするため、実行時にフラグメントで初期コンテンツを設定します


0

この問題を解決した後、私は同じ問題を抱えていました

  1. uがurフラグメントを置き換えているフレームレイアウトを取得します

    <FrameLayout
                    android:id="@+id/fragment_place"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
  2. と交換のためのコード

    public void selectFrag(View view) {
    Fragment fr;
    
      if(view == findViewById(R.id.button2))
    {
         fr = new FragmentTwo();
    
     }else {
         fr = new FragmentOne();
     }
     FragmentManager fm = getFragmentManager();
     FragmentTransaction fragmentTransaction = fm.beginTransaction();
     fragmentTransaction.replace(R.id.fragment_place, fr);
     fragmentTransaction.commit();

例全体が必要な場合は、コメントを送信します......


0

私も同じ問題を抱えていましたが、フレームレイアウトに追加しようとしていたのは、フラグメントの背景色を変更していないためです。

これを試してlayout_height、にlayout_width設定してくださいmatch_parent


0

私はかつてこの問題を抱えていて、それがandroid:backgroundxmlコードに欠けている属性を誤って削除したことが原因であることがわかりました。壁を塗っているときのように機能すると思います。壁android:backgroundの色で、他のビューはその基本色の上に配置されます。ビューを配置する前に壁をペイントしないと、ビューはすでにその壁にあったもの、つまり他のフラグメントの上に配置されます。それがあなたに役立つかどうかわからない、幸運。


0

私は上記のすべてのケースを試し、問題を修正しようとしましたが、まだ解決策がありません。なぜうまくいかないのか分かりません。多くの人がそれに同意しているので、私は上記の回答に同意します。

私は答えを拡張しているだけで、以下は私のために働いている方法です。

このプロパティandroid:clickable="true"fragment.xmlファイルの一番上の親レイアウトに追加しました。

私は誰かが助けを得ると思います。


0

Sapan Diwakarさん、ありがとうございました。この答えは私を助けました。フラグメントを含まないRelativeLayoutを作成し、親ビューまたはグループビューとしてRelativeLayoutを使用し、トランザクションでそのグループビューを指定して置き換えると、機能しました。

コード:

getSupportFragmentManager().beginTransaction()
                            .replace(R.id.content_group_view, itemDetailFragment).commit();

XML:

 <RelativeLayout
         android:id="@+id/content_group_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

 </RelativeLayout>

0

フレームレイアウトIDを確認し、以下のように置き換えます

fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.