FragmentPagerAdapter getItem çağrılmaz


123

FragmentPagerAdapter'da parçayı yeniden kullanamıyorum .. destroyItem () yöntemini kullanarak, parçayı siliyor ancak yine de getItem () 'i çağırmıyor ... Yalnızca 2-3 Görüntü var, bu yüzden FragmentStatePagerAdapter yerine FragmentPagerAdapter kullanıyorum ..

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

Ve FragmentActivity'de,

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

3
Aşmanızın belirli bir nedeni var destroyItem()mı? Bu gerekli değil.
CommonsWare

yeniden başlatmak için FragmentStatePagerAdapter'ı kullanın, super.destroyItem'i (konteyner, konum, nesne) geçersiz kıldığınızda da çağırın;
faiziii

Yanıtlar:


306

KISS Cevap:

Basit kullanım FragmentStatePagerAdapter yerine FragmentPagerAdapter .

Cevabı aldım .. Öncelikle çok aptalca bir hata yaptığım için bu soruyu silmeyi düşündüm ama bu cevap yerine FragmentPagerAdapterkullanmakla aynı problemle karşılaşan birine yardımcı olacaktır FragmentStatePagerAdapter.

@BlackHatSamurai'nin yorumda bahsettiği gibi:

Bunun işe FragmentStatePagerAdapteryaramasının nedeni, kullanılmayan Parçalar olarak yok edilmesidir. FragmentPagerAdapterdeğil.


Çok teşekkürler, cevabım bana çok yardımcı oldu.
Priya

1
Başka bir 'ben de' olmaktan nefret ediyorum! gönder, ama evet>. <Soruyu silmediğiniz için teşekkürler.
Paul Ruiz

34
Bunun çalışmasının nedeni FragmentStatePagerAdapter'ın kullanılmayan Parçalar olarak yok etmesidir. FragmentPagerAdapter yapmaz.
BlackHatSamurai

3
Sadece, yaşadıkları belirli bir sorunu ararken bunu bulabilecekler için gelecekteki referans için; FragmentPagerAdapter ve FragmentStatePagerAdapter üzerinde okuyun. Bir nedenden ötürü farklı davranırlar ve özel kullanımınız diğerine göre birini gerektirebilir.
Chris Stewart

2
@najibputhawala FragmentStatePagerAdapter kullandım ama hala aynı sorunla karşılaşıyorum. getItem () çağrılmadı
sam_k

168

A kullanmak , görünüm çağrı cihazında alt parçalar için çağrılmayan FragmentStatePagerAdapterbenzer bir sorun olan sorunumu tam olarak çözmedi onCreateView. Aslında içimi bir FragmentPagerAdapterbaşkasının içine yerleştiriyorum,Fragment bu nedenle FragmentManagerhepsi arasında paylaşıldı ve böylece eski parçaların örneklerini korudu. Düzeltme, bunun yerine öğesinin bir örneğini ana bilgisayar parçamdaki getChildFragmentManageryapıcısına beslemekti FragmentPagerAdapter. Gibi bir şey...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

getChildFragmentManager()Yöntem, bir parçası aracılığıyla erişilebilir ve özel döndürdüğü için bu benim için çalıştı FragmentManager, özellikle yuvalama fragmanları gerekli olduğu durumlar için bu parça için. Umarım bu benimle aynı sorunu yaşayan birine yardımcı olur !!

  • Bununla birlikte getChildFragmentManager(), minimum API sürümünüzü kullanmak için en az olması gerektiğini unutmayın 17 (4.2), bu nedenle bu, dişlilerinize bir anahtar atabilir. Tabii ki, destek kitaplığı v4'ten parçalar kullanıyorsanız, sorun yaşamazsınız.

25
Bu doğru cevap. Sorun, diğer parçalarda yuvalanmış parçaların getFragmentManager () yerine getChildrenFragmentManager () kullanması gerektiğinden kaynaklanmaktadır.
shihpeng

Çok teşekkür ederim, bu cevabı bulmam sonsuza kadar sürdü!
Shpongoloid

@Shihpeng'e katılıyorum. Bu doğru cevap olmalı.
Raymond Lukanta

Bu benim için bir düzeltmeydi. Cevap gönderdiğiniz için çok teşekkür ederiz
user3734429

Doktorlar bunu gerçekten yürüyüşte açıklamalı. ViewPager'ın bir parçanın içine yükleneceği son derece gerçekçidir. Bu cevabı gönderdiğiniz için teşekkürler.
çalıştı

7

Geçersiz Kıl long getItemId (int position)

FragmentPagerAdapterkullanarak oluşturduğu parçaları önbelleğe alır getItem. Aynı sorunla karşı karşıyaydım - aradıktan sonra bile aranmamıştım notifyDataSetChanged() getItem.

Bu aslında bir özelliktir ve bir hata değildir. getItemIdParçalarınızı doğru şekilde yeniden kullanabilmek için geçersiz kılmanız gerekir. Parçaları çıkardığınız için konumlarınız değişiyor. Dokümanlarda belirtildiği gibi:

long getItemId (int position)

Verilen konumdaki öğe için benzersiz bir tanımlayıcı döndür.

Varsayılan uygulama, verilen konumu döndürür. Öğelerin konumları değişebiliyorsa, alt sınıflar bu yöntemi geçersiz kılmalıdır.

Sadece her parçaya benzersiz bir kimlik sağlayın ve bitirdiniz.

Bir kullanılması FragementStatePagerAdapterveya geri dönen POSITION_NONEiçinde int getItemPosition (Object object)yanlıştır. Herhangi bir önbellek almayacaksınız.


Bu doğru cevaptı. Parçalar için farklı kimlikler sağlamak zorunda kaldım getItemIdVE parçanın çıkarılması gerekiyorsa EĞER getItemPositiondöndürmek için ayarladım POSITION_NONE. Bunun için bir sıralama bayrağım var. Bundan sonra getItemaranacak.
Murat Karagöz

Teşekkürler @ MuratKaragöz +50 için :)
vedant

5

@Kanika ve @ Jraco11'in gönderdiklerini yaptım ama hala sorun yaşadım.

Bu yüzden, birçok değişiklikten sonra, benim için çalışan bir tane buldum ve FragmentPagerAdapter'ıma bir sonraki koda ekledim:

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

Okuduğuma göre getItemPosition , ViewPager'a bir öğeyi yenileyip yenilemeyeceğini bildirmek ve görünür konumlardaki öğeler değişmediyse güncellemeleri önlemek için kullanılıyor.


2

İki farklı senaryo vardır: 1.) Her çağrı cihazı için aynı düzene sahipsiniz: Bu durumda, özel bağdaştırıcınızı PagerAdapter ile genişletip tek bir düzen döndürmeniz daha iyi olacaktır.

2.) Her çağrı cihazı için farklı bir düzene sahipsiniz: Bu durumda, özel adaptörünüzü FragmentStatePagerAdapter ile genişletmeniz ve her çağrı cihazı için farklı fragmanlar döndürmeniz daha iyi olacaktır.


2

yöntemi getItem()yalnızca yeni öğeler oluşturmak için kullanılır. Oluşturulduktan sonra bu yöntem çağrılmayacaktır. Bağdaştırıcı tarafından kullanılan para birimi olan bir öğeyi almanız gerekiyorsa, şu yöntemi kullanın:

pagerAdapter.instantiateItem(viewPager, TAB_POS)

0

Sekme düzeninde bir dinleyici ayarlamanın, bunun çağrılmasını engellediğini fark ettim, çünkü muhtemelen bir dinleyici tabLayout.setOnTabSelectedListenerdizisi yerine yalnızca bir dinleyici için yer var .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.