Tampilkan sembunyikan fragmen di android


100

Saya sedang mengembangkan aplikasi yang berisi 2 fragmen dan saya ingin menampilkan hide sesuai kebutuhan saya. Kode berikut memiliki contoh sederhana dari masalah saya. Fragmentactivity sederhana ini berisi 1 tombol dan satu listfragment.

Contoh sederhana ini bekerja dengan sempurna. tapi saya tidak puas dengan show hide fragment. Jika Anda menghapus layout.setVisibility (View.GONE); dari kode lalu ft.hide (f); tidak akan menyembunyikan fragmen. Sebenarnya kami tidak menyembunyikan fragmen kami menyembunyikan wadah.

Pertanyaan saya adalah, apakah ini cara untuk menampilkan fragmen tersembunyi? Jika tidak, mohon jelaskan dengan contoh teruji Cara menyembunyikan dan menampilkan Fragmen karena banyak orang menghadapi masalah ini.

 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
        }

Mengapa Anda perlu menyetel visibilitas penampung? Ini harus bekerja tanpa mengatur visibilitas.
Andrii Chernenko

Sebenarnya itu harus bekerja tanpa visibilitas wadah tetapi tidak berfungsi. Tolong tolong bagikan contoh kerja sederhana dengan saya. Kemudian saya akan tahu di mana saya hilang.
abidkhan303

1
Dugaan saya adalah bahwa Anda mencoba menampilkan / menyembunyikan contoh fragmen yang berbeda setiap kali. Ketika Anda menambahkan fragmen Anda (omong-omong, saya tidak melihat potongan kode ini) tambahkan dengan tag dan kemudian ambil dengan tag itu (alih-alih mencoba menyimpan referensi ke sana). Mungkin itu yang Anda lewatkan.
Andrii Chernenko

Jawaban:


159

Jangan mengacaukan bendera visibilitas penampung - FragmentTransaction.hide / show melakukannya secara internal untuk Anda.

Jadi cara yang benar untuk melakukannya adalah:

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

ATAU jika Anda menggunakan 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
Mengapa Anda merekomendasikan untuk tidak mengotak-atik bendera secara langsung? (Saya tidak membantah rekomendasi Anda, hanya mencoba untuk memahaminya.)
Ellen Spertus

1
Ya, saya membacanya di pesan asli Anda. Saya berharap Anda bisa menambahkan pembenaran untuk biaya tambahan. Sementara itu, saya telah menemukan beberapa, seperti opsi untuk menambahkan ke back-stack.
Ellen Spertus

2
Ini rawan kesalahan karena Anda dapat mengubah bendera Anda pada api tingkat rendah dan api tingkat tinggi dan jika Anda tidak berhati-hati (yaitu, bendera tidak sinkron) Anda bisa mengejar bug aneh. Itulah mengapa disarankan untuk menggunakan pengelola fragmen untuk menyembunyikan dan menampilkan fragmen Anda.
numan salati

@numansalati Hai, apakah ada versi yang kompatibel (dari pustaka dukungan) dari android.R.animator.fade_in, dan android.R.animator.fade_out?
Penghiburan

1
Dengan penampung, Anda dapat mengaturnya ke SHOW, HIDE, atau GONE. Tidak ada opsi GONE saat menyembunyikan fragmen.
Stealth Rabbi

58

Selain itu, Anda dapat melakukannya di Fragment (misalnya saat mendapatkan data server gagal):

 getView().setVisibility(View.GONE);

11
Fragment adalah anak dari Object dan bukan View sehingga seseorang tidak dapat memanggil: fragment.setVisibility (View.INVISIBLE);
AndroidGeek

8
Arià menyarankan sesuatu yang berbeda, menyarankan untuk mendapatkan pandangan dari fragmen itu dan menyetel visibilitasnya menjadi hilang.
AlvaroSantisteban

10
Berhati getView()- hatilah nullsaat belum diinisialisasi.
TWiStErRob

23

Hai, Anda melakukannya dengan menggunakan pendekatan ini, semua fragmen akan tetap berada di wadah setelah ditambahkan pada awalnya dan kemudian kami hanya mengungkapkan fragmen yang diinginkan dan menyembunyikan yang lain di dalam wadah.

// 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();
}

Silakan lihat https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments untuk info lebih lanjut. Saya harap saya bisa membantu siapa pun. Meskipun ini adalah pertanyaan lama.


1
jadi Anda harus memiliki dua metode lagi seperti displayFragmentB () dan displayFragmentC ()?
temirbek

ya @temirbek Anda bisa mengikuti bagaimana metode displayFragmentA () diimplementasikan.
mangu23

1
Jika Anda memiliki banyak fragmen dalam satu aktivitas (2 atau lebih) dan Anda menggunakan metode di atas, gunakan ini . Akan lebih mudah untuk menulis dan membaca.
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
yang benar adalah ft.setCustomAnimations (android.R.anim.fade_in, android.R.anim.fade_out);
Webserveis

8

Coba ini:

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

2

Dari kode saya, dibandingkan dengan solusi di atas, cara paling sederhana adalah dengan mendefinisikan tata letak yang berisi fragmen, lalu Anda dapat menyembunyikan atau menampilkan fragmen dengan mengontrol atribut tata letak yang selaras dengan cara pandang umum. Tidak diperlukan kode tambahan dalam kasus ini dan atribut penerapan tambahan dari fragmen dapat dipindahkan ke tata letak luar.

<LinearLayout style="@style/StHorizontalLinearView"
    >

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

</LinearLayout>

0

Ini berhasil untuk saya

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

jawaban di sini benar dan saya suka @Jyo the Whiff ide dari pertunjukan dan sembunyikan implementasi fragmen kecuali cara yang dia miliki saat ini akan menyembunyikan fragmen saat pertama kali dijalankan jadi saya menambahkan sedikit perubahan karena saya menambahkan cek dan pertunjukan yang ditambahkan fragmen jika belum

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;

Di onCreate, setelah setContentView, saya menyembunyikan dua fragmen dan memasukkannya ke pengelola fragmen, tetapi saya tidak menyembunyikan fragmen pertama yang akan berfungsi sebagai rumah.

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;
}

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


0

Saya mungkin sangat terlambat tetapi itu bisa membantu seseorang di masa depan.
Jawaban ini merupakan modifikasi untuk mangu23 menjawab
Saya hanya menambahkan loop for untuk menghindari pengulangan dan untuk dengan mudah menambahkan lebih banyak fragmen tanpa kode boilerplate.

Pertama-tama kita membutuhkan daftar fragmen yang harus ditampilkan

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

Kemudian kita perlu mengisinya dengan fragmen kita

@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);
}

Dan kami membutuhkan cara untuk mengetahui fragmen mana yang dipilih dari daftar, jadi kami membutuhkan getFragmentIndexfungsi

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;
}

Dan akhirnya, displayFragmentcaranya akan seperti ini:

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();
    }

Dengan cara ini, kita dapat memanggil displayFragment(homeFragment)misalnya.
Ini secara otomatis akan menampilkan HomeFragmentdan menyembunyikan fragmen lain dalam daftar.
Solusi ini memungkinkan Anda untuk menambahkan lebih banyak fragmen ke fragmentListtanpa harus mengulangi ifpernyataan di displayFragmentversi lama .
Saya berharap seseorang akan merasakan manfaatnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.