จะเปลี่ยนหน้าของ ViewPager ได้อย่างไร?


150

ฉันใช้ ViewPager ในแอพของฉันและกำหนดไว้ในกิจกรรมหลัก onCreateวิธีการภายในฉันโหลดบางหน้าจาก SharedPreferences แล้วส่งไปที่ PagerAdapter:

@Override
public int getCount() {
    return numberOfPages;
}

ปัญหาคือถ้าฉันจะเปลี่ยนหมายเลขนี้ในการตั้งค่า (หรือกิจกรรมอื่น) ให้น้อยกว่าดัชนีหน้าฉันดูก่อนหน้านี้แอปของฉันเกิดปัญหาเพราะดัชนีนี้อยู่นอกขอบเขตเมื่อฉันกลับไปที่กิจกรรมด้วย ViewPager นี้ สามารถแก้ไขได้ง่ายๆโดยเปลี่ยนหน้าของ ViewPager ที่ใช้งานอยู่ มีวิธีใดบ้างที่จะทำ?

คำตอบ:


394

ผมไม่แน่ใจว่าผมเข้าใจคำถาม pager.setCurrentItem( num )แต่จากชื่อของคำถามของคุณผมคาดเดาว่าสิ่งที่คุณกำลังมองหาอยู่ ที่ช่วยให้คุณ programatically ViewPagerสลับไปยังหน้าอื่นภายใน

ฉันต้องการดู stack trace จาก logcat ให้เจาะจงยิ่งขึ้นหากนี่ไม่ใช่ปัญหา


3
ใช่นั่นคือสิ่งที่ฉันต้องการ ผมตั้งค่าให้0อยู่ในonPauseวิธีการและไม่มีการเกิดปัญหา ขอบคุณ
โรมัน

1
มีเอกสารน้อยมากใน ViewPager +1 สำหรับสิ่งนั้น
Arnab Chakraborty

1
ถ้าเพจเจอร์ของคุณใช้เวลาในการโหลดหน้ามากกว่าที่คุณสามารถใช้ setOffscreenPageLimit (1), เพราะเพจเจอร์มุมมองเริ่มต้นโหลดเพจเจอร์ที่โหลด +1 และ -1 จากตำแหน่งปัจจุบัน
Ajay Pandya

สิ่งนี้ใช้งานไม่ได้ฉันเพิ่งได้รับข้อผิดพลาดที่แจ้งว่ามีการเพิ่มแฟรกเมนต์แล้ว
BlondeSwan

24

เลื่อนไปทางขวา

viewPager.arrowScroll (View.FOCUS_RIGHT);

เลื่อนไปทางซ้าย

viewPager.arrowScroll (View.FOCUS_LEFT);


สั้นและสะอาด!
dakshbhatt21

1
ฉันเกือบจะเชื่อว่านี่ควรเป็นคำตอบที่ได้รับการยอมรับ มันมีประโยชน์มากกว่าการตั้งค่ารายการปัจจุบัน
ปีเตอร์

18

หากไม่ตรวจสอบรหัสของคุณฉันคิดว่าสิ่งที่คุณอธิบายคือหน้าเว็บของคุณไม่ซิงค์และคุณมีข้อมูลเก่า

คุณบอกว่าคุณกำลังเปลี่ยนจำนวนหน้าจากนั้นหยุดทำงานเนื่องจากคุณเข้าถึงชุดหน้าเก่า ฟังดูเหมือนฉันจะไม่โทรหาคุณpageAdapter.notifyDataSetChanged()หลังจากเปลี่ยนข้อมูล

เมื่อคุณviewPagerแสดงหน้า 3 ของชุด 10 หน้าและคุณเปลี่ยนเป็นชุดที่มีเพียง 5 ชุดจากนั้นโทรnotifyDataSetChanged()สิ่งที่คุณจะพบคือตอนนี้คุณกำลังดูหน้า 3 ของชุดใหม่ หากก่อนหน้านี้คุณกำลังดูหน้า 8 ของชุดเก่าหลังจากใส่ชุดใหม่แล้วโทรหาnotifyDataSetChanged()คุณคุณจะพบว่าคุณกำลังดูหน้าสุดท้ายของชุดใหม่โดยไม่ต้องหยุดทำงาน

หากคุณเพียงแค่เปลี่ยนหน้าปัจจุบันของคุณคุณก็อาจจะกำบังปัญหา


1
บวก 1 สำหรับ informDataSetChanged ()
madhu527

@Richard คุณช่วยเพื่อนวันของฉัน 10,000+ สำหรับnotifyDataSetChanged()
Ali

15

สำหรับเปลี่ยนเป็นหน้าอื่นลองด้วยรหัสนี้:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);

1
ที่สมบูรณ์แบบ! ฉันพยายามใช้โดยไม่ใช้วิธี postDelay และใช้งานไม่ได้ คุณรู้ไหมว่าทำไมมันถึงใช้ได้กับวิธีนี้ ขอบคุณ! :)
Georgi Koemdzhiev

คำถามเดียวกัน ... ทำไมรายการถึงเปลี่ยนไปด้วยความล่าช้านี้และไม่เป็นอย่างอื่น?
Kalyan Raghu

@GeorgiKoemdzhiev เพราะมุมมองยังไม่เสร็จขณะที่คุณกำลังโทรviewPager.setCurrentItem
Zohab Ali

3

คำตอบเพิ่มเติม

ผมก็เดิมมีปัญหาในการรับการอ้างอิงไปViewPagerจากวิธีการเรียนอื่น ๆ เพราะaddOnTabSelectedListenerทำระดับชั้นที่ไม่ระบุชื่อซึ่งจะจำเป็นตัวแปรที่จะได้รับการประกาศViewPager finalวิธีแก้ไขคือใช้ตัวแปรสมาชิกคลาสและไม่ใช้คลาสภายในที่ไม่ระบุชื่อ

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        // don't use an anonymous inner class here
        tabLayout.addOnTabSelectedListener(tabListener);

    }

    TabLayout.OnTabSelectedListener tabListener = new TabLayout.OnTabSelectedListener() {

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    };

    // The view pager can now be accessed here, too.
    public void someMethod() {
        viewPager.setCurrentItem(0);
    }

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