Androidでフラグメントを非表示にする


98

2つのフラグメントを含むアプリケーションを開発しています。必要に応じて非表示にしたいと思います。次のコードは私の問題の簡単な例です。この単純なFragmentactivityには、1つのボタンと1つのリストフラグメントが含まれています。

この簡単な例は完璧に機能します。しかし、私はフラグメントの非表示に満足していません。layout.setVisibility(View.GONE);を削除すると、コードからft.hide(f); フラグメントを非表示にしません。実際、私たちはコンテナを隠しているフラグメントを隠していません。

私の質問は、これは非表示のフラグメントを表示する方法ですか?そうでない場合は、テスト済みの例で説明してください。多くの人がこの問題に直面しているため、フラグメントを非表示および表示する方法を説明してください。

 public class MainActivity extends FragmentActivity implements OnClickListener {

        Fragment1 f;
        Button b;
        LinearLayout layout;
        Fragment myf;
        @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            b = (Button) findViewById(R.id.button1);
            layout = (LinearLayout) findViewById(R.id.ll);
            f = new Fragment1();
        }

        @Override
        public void onClick(View v) {

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

            if (f.isHidden()) {
                ft.show(f);
                layout.setVisibility(View.VISIBLE);
                b.setText("Hide");
            } else {
                ft.hide(f);
                b.setText("Show");
                layout.setVisibility(View.GONE);
            }
            ft.commit();
            // TODO Auto-generated method stub
        }

なぜコンテナの可視性を設定する必要があるのですか?可視性を設定しなくても機能するはずです。
Andrii Chernenko 2013

正確には、コンテナが見えなくても機能するはずですが、機能しません。簡単な作業例を教えてください。その後、私はどこに行方不明かを知っています。
abidkhan303 2013年

1
私の推測では、毎回フラグメントの異なるインスタンスを表示/非表示にしようとしていると思います。フラグメントを追加するとき(ちなみに、このコードは表示されません)、それをタグ付きで追加し、(その参照を格納するのではなく)そのタグでフラグメントを取得します。それはあなたが見逃しているものかもしれません。
Andrii Chernenko 2013

回答:


158

コンテナの可視性フラグをいじらないでください-FragmentTransaction.hide / showは内部的にそれを行います。

したがって、これを行う正しい方法は次のとおりです。

FragmentManager fm = getFragmentManager();
fm.beginTransaction()
          .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
          .show(somefrag)
          .commit();

または、android.support.v4.app.Fragmentを使用している場合

 FragmentManager fm = getSupportFragmentManager();
 fm.beginTransaction()
          .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
          .show(somefrag)
          .commit();

5
なぜフラグを直接いじらないように勧めるのですか?(私はあなたの提案に異議を唱えているのではなく、それを理解しようとしているだけです。)
エレン・スペルタス14

1
はい、元のメッセージで読みました。私はあなたが余分なオーバーヘッドの正当化を追加できることを望んでいました。その間に、バックスタックに追加するオプションなど、いくつかを発見しました。
Ellen Spertus 14

2
低レベルのAPIと高レベルのAPIでフラグを変更できるため、エラーが発生しやすく、注意しないと(つまり、フラグが同期しなくなる)、奇妙なバグを追跡する可能性があります。そのため、フラグメントマネージャーを使用してフラグメントを非表示および表示することが推奨されています。
numan salati 2014

@numansalatiこんにちは、サポートライブラリからの互換性のあるバージョンはandroid.R.animator.fade_inありandroid.R.animator.fade_outますか?
Solace

1
コンテナでは、SHOW、HIDE、またはGONEに設定できます。フラグメントを非表示にする場合、GONEオプションはありません。
ステルスラビ

57

さらに、フラグメントで実行できます(たとえば、サーバーデータの取得に失敗した場合)。

 getView().setVisibility(View.GONE);

11
FragmentはObjectの子であり、Viewではないため、以下を呼び出すことはできません。fragment.setVisibility(View.INVISIBLE);
Zar E Ahmer 2014

8
アリアは別のことを提案し、そのフラグメントからのビューを取得し、その可視性を削除することを提案しています。
AlvaroSantisteban 2014年

10
まだ初期化されていない場合は注意getView()が必要nullです。
TWiStErRob 2015年

22

こんにちは、このアプローチを使用してそれを行います。最初に追加された後、すべてのフラグメントはコンテナーに残ります。その後、目的のフラグメントを明らかにし、コンテナー内の他のフラグメントを非表示にします。

// Within an activity
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    }
}


// Replace the switch method
protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

詳細については、https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragmentsを参照してください。誰かを助けたいと思います。それは古い質問ですが。


1
そのため、displayFragmentB()やdisplayFragmentC()のような2つのメソッドが必要ですか?
テミルベク2017年

はい@temirbekあなたは単にdisplayFragmentA()メソッドが実装されている方法に従うことができます。
mangu23

1
1つのアクティビティ(2つ以上)に多数のフラグメントがあり、上記の方法を使用している場合は、これを使用しください。書きやすく、読みやすくなります。
Maxime Claude

8
public void showHideFragment(final Fragment fragment){

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.animator.fade_in,
                    android.R.animator.fade_out);

    if (fragment.isHidden()) {
        ft.show(fragment);
        Log.d("hidden","Show");
    } else {
        ft.hide(fragment);
        Log.d("Shown","Hide");                        
    }

    ft.commit();
}

1
正しいのはft.setCustomAnimations(android.R.anim.fade_in、android.R.anim.fade_out);です。
Webserveis 2017

8

これを試して:

MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.mapview);
mapFragment.getView().setVisibility(View.GONE);

2

上記のソリューションと比較して私のコードから、最も簡単な方法は、フラグメントを含むレイアウトを定義することです。次に、一般的なビューの方法に合わせたレイアウト属性を制御することにより、フラグメントを非表示または再表示できます。この場合、追加のコードは必要なく、フラグメントの追加のデプロイメント属性を外部レイアウトに移動できます。

<LinearLayout style="@style/StHorizontalLinearView"
    >

    <fragment
        android:layout_width="match_parent"
        android:layout_height="390dp"
        android:layout_alignParentTop="true"
        />

</LinearLayout>

0

これは私のために働いた

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        if(tag.equalsIgnoreCase("dashboard")){

            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.show(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.hide(showcaseFragment);

        } else if(tag.equalsIgnoreCase("showcase")){
            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.hide(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.show(showcaseFragment);
        }

        ft.commit();

0

ここでの答えは正しく、@ Jyo the Whiffのショーのアイデアが好きで、フラグメントの実装を非表示にしていますが、最初の実行時にフラグメントを非表示にするため、isAddedチェックと表示を追加することで少し変更を加えましたフラグメントがまだない場合

public void showHideCardPreview(int id) {
    FragmentManager fm = getSupportFragmentManager();
    Bundle b = new Bundle();
    b.putInt(Constants.CARD, id);
    cardPreviewFragment.setArguments(b);
    FragmentTransaction ft = fm.beginTransaction()
        .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (!cardPreviewFragment.isAdded()){
        ft.add(R.id.full_screen_container, cardPreviewFragment);
        ft.show(cardPreviewFragment);
    } else {
        if (cardPreviewFragment.isHidden()) {
            Log.d(TAG,"++++++++++++++++++++ show");
            ft.show(cardPreviewFragment);
        } else {
            Log.d(TAG,"++++++++++++++++++++ hide");
            ft.hide(cardPreviewFragment);
        }
    }

    ft.commit();
} 

0
final Fragment fragment1 = new fragment1();
final Fragment fragment2 = new fragment2();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;

onCreateでは、setContentViewの後、2つのフラグメントを非表示にしてフラグメントマネージャーにコミットしましたが、ホームとして機能する最初のフラグメントを非表示にしませんでした。

fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();
 @Override
    public void onClick(View v) {
        Fragment another = fragment1;
         if(active==fragment1){
          another = fragment2;
         }
            fm.beginTransaction().hide(active).show(another).commit();
            active = another;
}

参照:https : //medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711


0

私は遅すぎるかもしれませんが、将来誰かを助けることができるでしょう。
この答えは、 繰り返しを避け、ボイラープレートコードなしでフラグメントを簡単に追加するためにforループを追加しただけのmangu23 答えの変更
です。

私たちは、最初の必要なフラグメントのリストが表示されなければなりません

public class MainActivity extends AppCompatActivity{
    //...
    List<Fragment> fragmentList = new ArrayList<>();
}

次に、フラグメントで埋める必要があります

@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    HomeFragment homeFragment = new HomeFragment();
    MessagesFragment messagesFragment = new MessagesFragment();
    UserFragment userFragment = new UserFragment();
    FavoriteFragment favoriteFragment = new FavoriteFragment();
    MapFragment mapFragment = new MapFragment();

    fragmentList.add(homeFragment);
    fragmentList.add(messagesFragment);
    fragmentList.add(userFragment);
    fragmentList.add(favoriteFragment);
    fragmentList.add(mapFragment);
}

そして、どのフラグメントがリストから選択されたかを知る方法が必要なので、getFragmentIndex関数が必要です

private int getFragmentIndex(Fragment fragment) {
    int index = -1;
    for (int i = 0; i < fragmentList.size(); i++) {
        if (fragment.hashCode() == fragmentList.get(i).hashCode()){
            return i;
        }
    }
    return index;
}

そして最後に、displayFragmentメソッドは次のようになります。

private void displayFragment(Fragment fragment) {
        int index = getFragmentIndex(fragment);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (fragment.isAdded()) { // if the fragment is already in container
            transaction.show(fragment);
        } else { // fragment needs to be added to frame container
            transaction.add(R.id.placeholder, fragment);
        }
        // hiding the other fragments
        for (int i = 0; i < fragmentList.size(); i++) {
            if (fragmentList.get(i).isAdded() && i != index) {
                transaction.hide(fragmentList.get(i));
            }
        }
        transaction.commit();
    }

このようにして、displayFragment(homeFragment)たとえば呼び出すことができます。
これにより、が自動的に表示さHomeFragmentれ、リスト内の他のフラグメントが非表示になります。
このソリューションでは、古いバージョンのステートメントfragmentListを繰り返す必要なく、にフラグメントを追加できます。 私は誰かがこれが役に立つことを願っています。ifdisplayFragment

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.