Bir ViewPager'ın mevcut konumunu alma


84

Galeri widget'ıyla getSelectedItemPosition () kullanabildiğimi biliyorum; mevcut konumu almak için, ancak ViewPager'da öyle görünmüyor.

Bir dinleyici kurabileceğimi ve sayfa değiştirildiğinde konumu alabileceğimi biliyorum. Ama şu anki görüş konumunu istiyorum.

Yanıtlar:


94

Bir dinleyici oluşturun ve bunu görüntüleyicinizde ayarlayın:

/**
 * Get the current view position from the ViewPager by
 * extending SimpleOnPageChangeListener class and adding your method
 */
public class DetailOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {

    private int currentPage;

    @Override
    public void onPageSelected(int position) {
        currentPage = position;
    }

    public final int getCurrentPage() {
        return currentPage;
    }
}

4
Bunu kullanırken dikkat edin: getCurrentPage (), görünüm hiç değiştirilmediğinde her zaman 0 döndürür. Bazı nedenlerden dolayı ViewPager'a ilk görünümden başka bir görünümde girerseniz, beklediğiniz değer 0 olmamalıdır ... Görünüme her zaman ilk bakışta girmediğim için bununla ilgili bir sorunla karşılaştım. görünüm.
Brandon Romano

1
@Adam lütfen bana bu işlevi nasıl çağıracağımı söyler misiniz getCurrentPage
user3233280

Çok basit. Teşekkür ederim androidu.
whdals0


4

2019 Güncellemesi

Artık addOnPageChangeListenerSayfa konumundaki değişikliği Gözlemlemek için Sayfalayıcıyı Görüntüle'yi ayarlayabilirsiniz .

Bir dinleyici kurmak ve sayfa değiştirildiğinde konumu almak istediğinizden

mViewPager.addOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {}
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

            override fun onPageSelected(position: Int) {
                pagePosition.setText("" + position + "/" + galleryAdapter!!.count)
            }
        })

0

Size şimdi bunun bir hack olduğunu söylüyorum, bu nedenle olumsuz oy kullanmak için bir neden yok. Yani, ya özellikle size yardımcı olacak ya da olmayacak. Her iki durumda da, aşağıdaki açıklama bazı bilgiler sağlayacak ve topluluğa yardımcı olacaktır. Ayrıca bu çözüm, sahip olmayan eski API'ler için iyidir ViewPager.getCurrentItem().


Önce biraz bilgi. ViewPager'ın tüm alt öğelerini yinelerseniz ViewPager.getChildAt(x);ve her çocuk View (bir sayfa) ile toString()(veya getLeft()) çıktı alırsanız ve bunu her sayfa değiştirdiğinizde, çocukların görüntülendikleri mantıksal sırada olmayacaklarını fark edeceksiniz. sayfalara geri dönmeye başladığınızda (başa dönerek). Görünüşe göre, gereksiz çocuğu diziden kaldıracak ve ardından en yeni çocuğu diziye ekleyecektir. Yani, örneğin, daha sonra sayfa 3 değiştirildi sayfa 2 bakıyor diyelim, çocukların listenizin bu sırada olacak page 2, page 3, page 4anlamına ViewPager.getChildAt(1);Geçerli sayfayı dönecektir. Ancak, daha sonra 2. sayfaya (3. sayfadan itibaren) geri dönerseniz, çocuk listeniz bu sırada olacaktır page 2, page 3, page 1, yaniViewPager.getChildAt(1);mevcut sayfayı döndürmez. Bu bilgiyi kullanarak mevcut sayfayı ayıklamak için henüz basit bir mantık bulamadım. Çünkü arkadaki dizideki sayfaların getChildAtsırası, kullanıcının nasıl sayfalandığına bağlı olarak gelişigüzel bir sıradadır.

Bununla birlikte, bir hile çözümü geliştirdim. Bu işlevin tüm ortamlarda çalışıp çalışmayacağına dair hiçbir fikrim yok, ancak mevcut projem için çalışıyor. Sizin için değilse, o zaman farklı API seviyesinde bir sorun olduğundan şüpheleniyorum. Ama aslında diğer ortamlar için herhangi bir sorundan şüphelenmiyorum.

Şimdi etin üzerine. Fark ettiğim şey, sonucunun ViewPager.getChildAt(x).getLeft()ebeveyne göre bir tür yatay piksel koordinatına sahip olacağıydı. Bu yüzden, bu bilgiyi hangi görüntünün mevcut olduğunu ayıklamak için kullandım.

private int getCurrentPageIndex(ViewPager vp){
    int first,second,id1,id2,left;
    id1 = first = second = 99999999;
    View v;
    for ( int i = 0, k = vp.getChildCount() ; i < k ; ++i ) {
        left = vp.getChildAt(i).getLeft();
        if ( left < second ) {
            if ( left < first ) {
                second = first;
                id2 = id1;
                first = left;
                id1 = i;
            } else {
                second = left;
                id2 = i;
            }
        }
    }
    return id2;
}

Bu işlev muhtemelen şüpheli bir hack'tir çünkü getLeft()hepsini çözmenin değerine dayanır . Ama her çocuğun sol koordinatını alıyorum. Daha sonra bunu diğer değerlerle karşılaştırıyorum ve birinci ve ikinci sayfaları kaydedip ikinci sayfayı (mevcut sayfa) işlevden çıkarıyorum. Güzel çalışıyor gibi görünüyor.

Neden (sorabilirsin) sadece kullanmadım onClickListenterya da başka bir çözüm? Dinleyicileri, diğer sınıfları, sonuçsuz odaklamayı ve diğer şişkinlikleri dahil etmek zorunda kalmadan bunu yapmanın basit bir yolu olduğuna karar verdim. Ne yazık ki bu çözüm tam olarak basit değil. Ancak, şişkinliği, diğer sınıfları ve dinleyicileri ortadan kaldırır. Daha açık bir yol bulabilirsem, bu işlevi yeniden yazacağım. Ya da belki bu, bir başkasının bir aydınlanma yaşaması için içgörü sağlayacaktır.


1
beni kurtardın! bazı korkunç böcekleri vardı. neyin yanlış gittiğini bulamadım. Siz, efendim, bazilyonlarca olumlu oyu hak ediyorsunuz!
Nursultan Talapbekov

Teşekkürler baylar! Sanırım topluluk senin coşkunu paylaşmıyor.
Pezevenk Trizkit
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.