Dapatkan objek fragmen saat ini

175

Di saya main.xmlmiliki

  <FrameLayout
        android:id="@+id/frameTitle"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="@drawable/title_bg">
            <fragment
              android:name="com.fragment.TitleFragment"
              android:id="@+id/fragmentTag"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />

  </FrameLayout>

Dan saya mengatur objek fragmen seperti ini

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");

// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Ini mengatur berbagai jenis objek Fragmen ( FragmentType2,FragmentType3,...) pada waktu yang berbeda. Sekarang di beberapa titik waktu saya perlu mengidentifikasi objek mana yang saat ini ada.

Dalam singkat saya perlu melakukan sesuatu seperti ini:

Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle

Saya mencoba yang berikut ini

TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);

dan

    TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");

Tetapi kedua objek (titleFragmentById dan titleFragmentByTag) adalahnull
Apakah saya melewatkan sesuatu?
Saya menggunakan Compatibility Package, r3dan mengembangkan untuk API level 7.

findFragmentById()dan findFragmentByTag()akan bekerja jika kita telah menetapkan fragmen menggunakan fragmentTransaction.replaceatau fragmentTransaction.add, tetapi akan return nulljika kita telah menetapkan objek di xml (seperti apa yang telah saya lakukan di saya main.xml). Saya pikir saya kehilangan sesuatu di file XML saya.

Labeeb Panampullan
sumber
Apakah jawaban @CommonsWare membantu Anda, karena saya masih mendapatkan nol?
IntoTheDeep

Jawaban:

253

Sekarang di beberapa titik waktu saya perlu mengidentifikasi objek mana yang saat ini ada

Sebut findFragmentById()di FragmentManagerdan menentukan fragmen dalam Anda R.id.frameTitlekontainer.

CommonsWare
sumber
1
Terimakasih atas tanggapan Anda. Ini akan berfungsi jika kita telah menetapkan fragmen menggunakan fragmentTransaction.replace atau fragmentTransaction.addtetapi tidak akan mendapatkan jika kita telah menyetelnya di xml. Lihat hasil edit saya 2
Labeeb Panampullan
9
@ Labeeb P: Anda tidak dapat mengubah fragmen yang dideklarasikan di sumber daya tata letak.
CommonsWare
Membuat kelas untuk menahan tab / fragmen yang saat ini terlihat akan bekerja juga, saya hanya mencobanya. Semoga tidak ada kegagalan.
Skynet
@CommonsWare findFragmentByTagmengembalikan null untuk ActionBarTab. Dalam Activityperpanjangan ActionBarActivitysaya, saya pertama-tama menambahkan tab ActionBardan kemudian menemukannya!
Muhammad Babar
1
@MuhammadBabar: Anda dapat mencoba executePendingTransactions()pada FragmentManagersetelah menelepon commit()pada transaksi, meskipun saya belum mencoba ini. Atau Anda dapat menggunakan setContentView()untuk menggunakan file tata letak dengan <fragment>tag. Salah satu dari itu terjadi secara serempak, sehingga fragmen akan ada dalam onCreate()panggilan itu sendiri di mana Anda menggunakan executePendingTransaction()atau setContentView(). Kalau tidak, biasa FragmentTransactiondiproses secara tidak sinkron, dan itu bahkan tidak akan dimulai pada saat onCreate()berakhir.
CommonsWare
110

Coba ini,

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

ini akan memberi Anda fragmen saat ini, maka Anda dapat membandingkannya dengan kelas fragmen dan melakukan tugas Anda.

    if (currentFragment instanceof NameOfYourFragmentClass) {
     Log.v(TAG, "find the current fragment");
  }
Palu
sumber
Di mana harus meletakkan garis ini?
Anand Savjani
9
Kadang-kadang Anda harus menggunakan getSupportFragmentManager()sebagai gantinya, dan akan mendapatkan nol tanpa supportbagian
Muz
Hapus kutipan dari sekitar "NAMA KELAS FRAGMENT ANDA".
Alan Nelson
37

Saya pikir Anda dapat menggunakan event onAttachFragment mungkin berguna untuk menangkap fragmen mana yang aktif.

@Override
public void onAttachFragment(Fragment fragment) {
    // TODO Auto-generated method stub
    super.onAttachFragment(fragment);

    Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();

}
Hede Hodo
sumber
3
saya bisa mendapatkan fragmen mana yang saya lampirkan. Pertarungan saya adalah ketika saya mengubah orientasi maka saya harus menampilkan tampilan yang sama bukan tampilan lain jadi bagaimana melakukan ini.
Pengembang Androi
7
Ini tidak berfungsi karena tidak memperbarui fragmen aktif ketika Anda kembali.
Justin
1
@Justin jadi kita hanya perlu menggunakan onDetach juga dengan daftar
referensi lemah
12

Saya pikir Anda harus melakukan:

Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");

Alasannya adalah karena Anda mengatur tag "fragmentTag" ke fragmen terakhir yang telah Anda tambahkan (saat Anda menelepon ganti).

Niqo
sumber
Terima kasih, saya telah memperbaikinya. Ini kesalahan ketik saat menulis pertanyaan ini. Ini akan berfungsi jika kita telah menetapkan fragmen menggunakan fragmentTransaction.replace atau fragmentTransaction.addtetapi tidak akan mendapatkan jika kita telah menyetelnya di xml. Lihat hasil edit saya 2
Labeeb Panampullan
Terima kasih banyak! Memecahkan masalah saya!
Jonas Gröger
2
bukankah solusi ini berarti Anda harus meletakkan tag yang sama untuk beberapa fragmen? jika tidak, bagaimana Anda tahu fragmentTagtag untuk fragmen saat ini?
Thupten
12

Anda bisa mendapatkan daftar fragmen dan melihat yang terakhir.

    FragmentManager fm = getSupportFragmentManager();
    List<Fragment> fragments = fm.getFragments();
    Fragment lastFragment = fragments.get(fragments.size() - 1);

Tetapi terkadang (ketika Anda menavigasi kembali) ukuran daftar tetap sama tetapi beberapa elemen terakhir adalah nol. Jadi dalam daftar saya beralih ke fragmen bukan nol terakhir dan menggunakannya.

    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for(int i = fragments.size() - 1; i >= 0; i--){
                Fragment fragment = fragments.get(i);
                if(fragment != null) {
                    // found the current fragment

                    // if you want to check for specific fragment class
                    if(fragment instanceof YourFragmentClass) {
                        // do something
                    }
                    break;
                }
            }
        }
    }
Eluleci
sumber
3
Jangan gunakan getFragments()metode ini. Itu ditandai dengan @hidedan tidak seharusnya disertakan dengan jar perpustakaan dukungan. Seharusnya tidak dianggap sebagai bagian dari API yang diekspor.
James Wald
Heh, maka mereka seharusnya menciptakan metode yang memungkinkan Anda melakukan apa yang benar-benar getFragments()dilakukan, karena Anda cukup sering membutuhkannya. Saya pikir itu sebenarnya tersedia untuk umum sekarang juga.
EpicPandaForce
10

Ini adalah solusi paling sederhana dan berhasil untuk saya.

1.) Anda menambahkan fragmen Anda

ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();

2.)

FragmentManager fragmentManager = getSupportFragmentManager();

Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);

if(currentFragment.getTag().equals("fragment_tag"))

{

 //Do something

}

else

{

//Do something

}
Gau
sumber
9

Mungkin terlambat tapi saya harap ini membantu orang lain, juga @CommonsWare telah memposting jawaban yang benar.

FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");
Ahmad Ali Nasir
sumber
9
Ini tidak memungkinkan Anda untuk mendapatkan fragmen aktif, karena Anda belum tentu tahu id atau tag.
Justin
7

Mungkin cara paling sederhana adalah:

public MyFragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    for(Fragment fragment : fragments){
        if(fragment != null && fragment.getUserVisibleHint())
            return (MyFragment)fragment;
    }
    return null;
}

Ini berhasil untuk saya

madx
sumber
6

Anda dapat membuat bidang di Kelas Aktivitas induk Anda:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

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

}

Dan kemudian di dalam setiap kelas fragmen:

public class SomeFragment extends Fragment {

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

        ((MainActivity) getActivity()).fr = this;
}

Bidang 'fr' Anda adalah Objek fragmen saat ini

Ini bekerja juga dengan popBackStack ()

buxik
sumber
4

Saya tahu ini sudah lama, tapi saya akan di sini kalau-kalau ini membantu seseorang keluar.

The jawaban yang tepat sejauh ini adalah (dan yang dipilih) satu dari CommonsWare. Saya mengalami masalah yang sama seperti yang diposting, berikut ini

MyFragmentClass fragmentList = 
            (MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);

terus mengembalikan nol. Kesalahan saya benar-benar konyol, dalam file xml saya:

<fragment
    android:tag="@+id/fragementID"
    android:name="com.sf.lidgit_android.content.MyFragmentClass"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

Kesalahannya adalah saya punya android: tag BUKAN DARI android: id .

Chayemor
sumber
2

@Hammer response bekerja untuk saya, saya gunakan untuk mengontrol tombol aksi mengambang

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
            Log.d("VIE",String.valueOf(currentFragment));
            if (currentFragment instanceof PerfilFragment) {
                PerfilEdit(view, fab);
            }
        }
});
Thiago Melo
sumber
2

Jika Anda memperluas dari AbstractActivity, Anda bisa menggunakan metode getFragments ():

for (Fragment f : getFragments()) {
    if (f instanceof YourClass) {
        // do stuff here
    }
}
Marco Aurélio Alves Puton
sumber
1

Jika Anda mendefinisikan fragmen dalam tata letak XML aktivitas, maka Activitypastikan Anda menelepon setContentView()sebelum menelepon findFragmentById().

IvancityM
sumber
1

Jika Anda menggunakan BackStack ... dan ONLY jika Anda menggunakan back stack, cobalah ini:

rivate Fragment returnToPreviousFragment() {

    FragmentManager fm = getSupportFragmentManager();

    Fragment topFrag = null;

    int idx = fm.getBackStackEntryCount();
    if (idx > 1) {
        BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
        topFrag = fm.findFragmentByTag(entry.getName());
    }

    fm.popBackStack();

    return topFrag;
}
James Barwick
sumber
0

Ini akan memberi Anda nama kelas fragmen saat ini ->

String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Biplob Das
sumber
0
  1. Lakukan pemeriksaan (fragmen mana dalam wadah aktivitas) dalam metode onStart;

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. Beberapa cek:

    if (fragmentCurrent instanceof MenuFragment) 
Владислав Шестернин
sumber