FragmentPagerAdapter getItem tidak dipanggil


123

Saya tidak dapat menggunakan kembali fragmen di FragmentPagerAdapter .. Menggunakan metode destroyItem (), Ini menghapus fragmen tetapi masih tidak memanggil getItem () lagi..Hanya ada 2-3 Gambar jadi saya menggunakan FragmentPagerAdapter, bukan FragmentStatePagerAdapter ..

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

Dan Di FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 

3
Apakah ada alasan khusus Anda mengesampingkan destroyItem()? Itu tidak perlu.
CommonsWare

untuk menginisialisasi lagi gunakan FragmentStatePagerAdapter, juga panggil saat Anda menimpanya super.destroyItem (container, position, object);
faiziii

Jawaban:


306

KISS Jawaban:

Gunakan FragmentStatePagerAdapter secara sederhana, bukan FragmentPagerAdapter .

Saya mendapat jawabannya .. Pertama saya berpikir untuk menghapus pertanyaan ini karena saya melakukan kesalahan yang sangat konyol tetapi jawaban ini akan membantu seseorang yang menghadapi masalah yang sama daripada FragmentPagerAdaptermenggunakan FragmentStatePagerAdapter.

Seperti yang disebutkan @BlackHatSamurai di komentar:

Alasan ini berhasil adalah karena FragmentStatePagerAdaptermenghancurkan sebagai Fragmen yang tidak digunakan. FragmentPagerAdaptertidak.


Terima kasih banyak Jawaban Anda banyak membantu saya.
Priya

1
Benci menjadi 'aku juga!' posting, tapi ya>. <Terima kasih telah tidak menghapus pertanyaan.
Paul Ruiz

34
Alasan ini berfungsi adalah karena FragmentStatePagerAdapter dihancurkan sebagai Fragmen yang tidak digunakan. FragmentPagerAdapter tidak.
BlackHatSamurai

3
Hanya untuk referensi di masa mendatang bagi mereka yang mungkin menemukan ini saat mencari masalah khusus yang mereka hadapi; baca di FragmentPagerAdapter dan FragmentStatePagerAdapter. Mereka berperilaku berbeda karena suatu alasan dan penggunaan khusus Anda mungkin memerlukan salah satu dari yang lainnya.
Chris Stewart

2
@najibputhawala Saya menggunakan FragmentStatePagerAdapter tetapi masih menghadapi masalah yang sama. getItem () tidak dipanggil
sam_k

168

Menggunakan sebuah FragmentStatePagerAdapter tidak sepenuhnya memperbaiki masalah saya yang merupakan masalah serupa di mana onCreateViewtidak dipanggil untuk fragmen anak di halaman tampilan. Saya benar-benar menumpuk FragmentPagerAdapterdi dalam saya yang lainFragment karena FragmentManageritu dibagikan di semua dari mereka dan dengan demikian mempertahankan contoh dari fragmen lama. Perbaikannya adalah dengan memberi makan sebuah instance dari getChildFragmentManagerke konstruktor di FragmentPagerAdapterdalam fragmen host saya. Sesuatu seperti...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

The getChildFragmentManager()Metode dapat diakses melalui fragmen dan ini bekerja untuk saya karena mengembalikan swasta FragmentManageruntuk fragmen yang khusus untuk situasi di mana fragmen bersarang diperlukan. Saya harap ini membantu seseorang yang mungkin mengalami masalah yang sama dengan saya !!

  • Namun perlu diingat untuk menggunakan getChildFragmentManager() versi API minimum Anda harus minimal 17 (4.2), jadi ini dapat membuang kunci pas di gigi Anda. Tentu saja, jika Anda menggunakan fragmen dari support library v4 Anda akan baik-baik saja.

25
Ini jawaban yang benar. Masalahnya adalah fragmen yang disarangkan di fragmen lain harus menggunakan getChildrenFragmentManager (), bukan getFragmentManager ().
shihpeng

Terima kasih banyak, saya butuh waktu lama untuk menemukan jawaban ini!
Shpongoloid

Saya setuju dengan @shihpeng. Ini harus menjadi jawaban yang benar.
Raymond Lukanta

Yang ini adalah perbaikan bagi saya. Terima kasih banyak telah mengirimkan jawaban
pengguna3734429

Dokumen harus benar-benar menyebutkan hal ini saat berjalan-jalan. Sangat realistis bahwa ViewPager akan dimuat dalam sebuah fragmen. Terima kasih telah memposting jawaban ini.
bekerja

7

Mengesampingkan long getItemId (int position)

FragmentPagerAdaptermenyimpan cache fragmen yang dibuatnya menggunakan getItem. Saya menghadapi masalah yang sama - bahkan setelah meneleponnotifyDataSetChanged() getItem tidak dipanggil.

Ini sebenarnya adalah fitur dan bukan bug. Anda perlu mengganti getItemIdagar Anda dapat menggunakan kembali fragmen Anda dengan benar. Karena Anda menghapus fragmen, posisi Anda berubah. Seperti yang disebutkan dalam dokumen:

long getItemId (int position)

Kembalikan pengenal unik untuk item di posisi tertentu.

Implementasi default mengembalikan posisi yang diberikan. Subclass harus mengganti metode ini jika posisi item dapat berubah.

Cukup berikan id unik untuk setiap fragmen dan Anda selesai.

Menggunakan FragementStatePagerAdapteratau kembali POSITION_NONEdi int getItemPosition (Object object)salah. Anda tidak akan mendapatkan cache apa pun.


Yang ini adalah jawaban yang benar. Saya harus memberikan id yang berbeda untuk fragmen di getItemIdDAN menyesuaikan getItemPositionuntuk mengembalikan POSITION_NONEJIKA fragmen harus dihapus. Saya memiliki bendera enum untuk itu. Setelah itu getItemakan dipanggil.
Murat Karagöz

Terima kasih @ MuratKaragöz untuk +50 :)
vedant

5

Saya melakukan apa yang telah diposting @kanika dan @ Jraco11 tetapi saya masih mengalami masalah.

Jadi, setelah banyak perubahan, saya menemukan satu yang berfungsi untuk saya dan ditambahkan ke FragmentPagerAdapter saya kode berikutnya:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

Menurut apa yang saya baca, getItemPosition digunakan untuk memberi tahu ViewPager apakah akan menyegarkan item atau tidak, dan untuk menghindari pembaruan jika item pada posisi yang terlihat tidak berubah.


2

Ada dua skenario berbeda: 1.) Anda memiliki tata letak yang sama untuk setiap pager: Dalam hal ini, akan lebih baik jika Anda memperluas adaptor khusus Anda dengan PagerAdapter dan mengembalikan satu tata letak.

2.) Anda memiliki tata letak yang berbeda untuk setiap halaman: Dalam hal ini, akan lebih baik jika Anda memperluas adaptor kustom Anda dengan FragmentStatePagerAdapter dan mengembalikan fragmet yang berbeda untuk setiap halaman.


2

metode getItem()digunakan hanya untuk membuat item baru. Setelah dibuat, metode ini tidak akan dipanggil. Jika Anda perlu mendapatkan item mata uang yang digunakan oleh adaptor, gunakan metode ini:

pagerAdapter.instantiateItem(viewPager, TAB_POS)

0

Saya menemukan bahwa menyetel listener pada tab-layout menghentikan pemanggilan ini, mungkin karena mereka hanya memiliki ruang untuk satu listener di tabLayout.setOnTabSelectedListeneralih-alih array listener.

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.