การรับตำแหน่งปัจจุบันของ ViewPager


84

ฉันรู้ว่ามีวิดเจ็ตแกลเลอรีฉันสามารถใช้ getSelectedItemPosition (); เพื่อดึงตำแหน่งปัจจุบัน แต่ดูเหมือนว่า ViewPager จะไม่มี

ฉันรู้ว่าฉันสามารถตั้งค่าผู้ฟังและเรียกข้อมูลตำแหน่งได้เมื่อเปลี่ยนหน้า แต่ฉันต้องการตำแหน่งมุมมองปัจจุบัน

คำตอบ:


94

สร้าง Listener และตั้งค่าใน viewpager ของคุณ:

/**
 * 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
โปรดทราบเมื่อใช้สิ่งนี้: getCurrentPage () จะคืนค่า 0 เสมอเมื่อมุมมองไม่เคยเปลี่ยนแปลง ด้วยเหตุผลบางประการหากคุณเข้าสู่ ViewPager ในมุมมองอื่นที่ไม่ใช่มุมมองแรกค่าที่คุณคาดหวังไม่ควรเป็น 0 ... ฉันเพิ่งพบปัญหานี้เนื่องจากฉันไม่ได้เข้าสู่มุมมองในครั้งแรกเสมอไป ดู.
Brandon Romano

1
@Adam คุณช่วยบอกวิธีเรียกใช้ฟังก์ชันนี้ getCurrentPage ได้อย่างไร
user3233280

มันง่ายมาก ขอบคุณ androidu.
whdals0

193

คุณสามารถใช้ได้:

mViewPager.getCurrentItem()

ไม่มีเมธอด getCurrentItem ใน ViewPager
Dmitry Guselnikov


3
ขออภัยฉันผิด เพิ่งอัปเดตไลบรารีการสนับสนุนของฉันและวิธีนี้มีอยู่ในเวอร์ชันใหม่
Dmitry Guselnikov

4

อัปเดต 2019

ตอนนี้คุณสามารถตั้งค่า addOnPageChangeListenerใน View Pager เพื่อสังเกตการเปลี่ยนแปลงในตำแหน่งหน้า

เนื่องจากคุณต้องการตั้งค่าผู้ฟังและเรียกข้อมูลตำแหน่งเมื่อมีการเปลี่ยนเพจ

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

ฉันกำลังบอกคุณว่าตอนนี้มันเป็นการแฮ็กดังนั้นจึงไม่มีเหตุผลที่จะลงคะแนนด้วยเหตุผลนั้น ความหมายมันจะเป็นประโยชน์กับคุณโดยเฉพาะหรือไม่ ไม่ว่าจะด้วยวิธีใดคำอธิบายด้านล่างจะให้ข้อมูลเชิงลึกและเป็นประโยชน์ต่อชุมชน นอกจากนี้การแก้ปัญหานี้เป็นสิ่งที่ดีสำหรับ APIs ViewPager.getCurrentItem()เก่าที่ไม่ได้มี


ก่อนอื่นข้อมูลเล็กน้อย หากคุณวนซ้ำผ่านลูก ๆ ทั้งหมดของ ViewPager ด้วยViewPager.getChildAt(x);และพิมพ์ออกมาด้วยtoString()(หรือgetLeft()) มุมมองเด็กแต่ละหน้า (หน้า) จากนั้นทำสิ่งนี้ทุกครั้งที่คุณเปลี่ยนหน้าคุณจะสังเกตเห็นว่าเด็ก ๆ จะไม่อยู่ในลำดับตรรกะที่แสดง เมื่อคุณเริ่มย้อนกลับไปหน้า (เพจกลับไปที่จุดเริ่มต้น) เห็นได้ชัดว่ามันจะลบลูกที่ไม่จำเป็นออกจากอาร์เรย์จากนั้นต่อท้ายลูกใหม่ล่าสุดเข้ากับอาร์เรย์ ตัวอย่างเช่นสมมติว่าคุณกำลังดูหน้าที่ 2 จากนั้นเปลี่ยนเป็นหน้าที่ 3 รายชื่อลูกของคุณจะอยู่ในลำดับนี้page 2, page 3, page 4ซึ่งViewPager.getChildAt(1);จะส่งกลับหน้าปัจจุบัน แต่ถ้าคุณเปลี่ยนกลับไปที่หน้า 2 (จากหน้าที่ 3) รายชื่อลูกของคุณจะอยู่ในลำดับนี้page 2, page 3, page 1ซึ่งหมายความว่าViewPager.getChildAt(1);ไม่กลับหน้าปัจจุบัน ฉันยังไม่สามารถหาตรรกะง่ายๆในการกำจัดหน้าปัจจุบันโดยใช้ข้อมูลนี้ เนื่องจากลำดับของเพจในอาร์เรย์ด้านหลังgetChildAtอยู่ในลำดับที่กำหนดขึ้นโดยอิงจากวิธีการที่ผู้ใช้เพจไปรอบ ๆ

ดังที่กล่าวมาฉันได้พัฒนาวิธีแก้ไขแฮ็ค ฉันไม่รู้ว่าฟังก์ชันนี้จะทำงานได้ในทุกสภาพแวดล้อมหรือไม่ แต่ใช้ได้กับโปรเจ็กต์ปัจจุบันของฉัน ฉันสงสัยว่าถ้าไม่ใช่สำหรับคุณนั่นคือปัญหาของระดับ API ที่แตกต่างกัน แต่ฉันไม่สงสัยปัญหาใด ๆ สำหรับสภาพแวดล้อมอื่น ๆ

ตอนนี้เข้าสู่เนื้อ สิ่งที่ฉันสังเกตเห็นคือผลลัพธ์ของViewPager.getChildAt(x).getLeft()จะมีพิกัดพิกเซลแนวนอนบางประเภทที่สัมพันธ์กับพาเรนต์ ดังนั้นฉันจึงใช้ข้อมูลนี้เพื่อกำจัดมุมมองที่เป็นมุมมองปัจจุบัน

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

ฟังก์ชั่นนี้น่าจะเป็นการแฮ็กที่น่าสงสัยเพราะมันต้องอาศัยค่าในgetLeft()การคิดออกทั้งหมด แต่ฉันจับพิกัดด้านซ้ายของเด็กแต่ละคน จากนั้นฉันเปรียบเทียบสิ่งนี้กับค่าอื่น ๆ และจัดเก็บหน้าแรกและหน้าที่สองโดยส่งคืนหน้าที่สอง (หน้าปัจจุบัน) ออกจากฟังก์ชัน ดูเหมือนว่าจะทำงานได้อย่างสวยงาม

ทำไม (คุณอาจถาม) ฉันไม่ได้ใช้onClickListenterหรือวิธีแก้ปัญหาอะไรเลย? ฉันรู้สึกแย่แล้วว่ามีวิธีตรงไปตรงมาในการทำสิ่งนี้โดยไม่ต้องรวมผู้ฟังชั้นเรียนอื่น ๆ การโฟกัสที่สรุปไม่ได้และการขยายตัว น่าเสียดายที่การแก้ปัญหานี้ไม่ตรงไปตรงมา แต่มันจะไปกับการขยายตัวของชั้นเรียนอื่น ๆ และผู้ฟัง ถ้าฉันสามารถหาวิธีที่ตรงไปตรงมาได้มากขึ้นฉันจะเขียนฟังก์ชันนี้ใหม่ หรืออาจจะเป็นข้อมูลเชิงลึกสำหรับคนอื่นที่จะมีความศักดิ์สิทธิ์


1
คุณช่วยฉันไว้! มีข้อบกพร่องบางอย่างที่น่ากลัว ไม่พบสิ่งที่เกิดขึ้น คุณท่านสมควรได้รับคะแนนโหวตเพิ่มขึ้นเป็นพันล้าน!
Nursultan Talapbekov

ขอบคุณครับ! ฉันเดาว่าชุมชนไม่ได้แบ่งปันความกระตือรือร้นของคุณ
Pimp Trizkit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.