Nhận vị trí hiện tại của ViewPager


84

Tôi biết với tiện ích Thư viện, tôi đã có thể sử dụng getSelectedItemPosition (); để truy xuất vị trí hiện tại, tuy nhiên, có vẻ như ViewPager không có điều đó.

Tôi biết mình có thể thiết lập trình nghe và truy xuất vị trí khi chuyển trang. Nhưng tôi muốn vị trí xem hiện tại.

Câu trả lời:


94

Tạo trình nghe và đặt nó trên máy xem của bạ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
Chỉ cần lưu ý khi sử dụng điều này: getCurrentPage () sẽ luôn trả về 0 khi chế độ xem chưa bao giờ được thay đổi. Vì lý do nào đó nếu bạn nhập ViewPager trên một số chế độ xem khác với chế độ xem đầu tiên, giá trị bạn mong đợi không được bằng 0 ... Tôi chỉ gặp sự cố với điều này vì không phải lúc nào tôi cũng vào chế độ xem ở lần đầu tiên lượt xem.
Brandon Romano

1
@ Adam u có thể vui lòng cho tôi biết làm thế nào để gọi đây là chức năng getCurrentPage
user3233280

Nó rất đơn giản. Cảm ơn bạn androidu.
whdals:


4

Cập nhật 2019

Bây giờ, bạn có thể đặt addOnPageChangeListenertrên View Pager để Quan sát sự thay đổi ở vị trí Trang.

Vì bạn muốn thiết lập trình nghe và truy xuất vị trí khi trang được chuyển

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

-1

Tôi đang nói với bạn bây giờ nó là một vụ hack, vì vậy không có lý do gì để phản đối vì lý do đó. Có nghĩa là, nó sẽ hữu ích cho bạn cụ thể hoặc không. Dù bằng cách nào, mô tả bên dưới sẽ cung cấp một số thông tin chi tiết và hữu ích cho cộng đồng. Ngoài ra, giải pháp này cũng tốt cho các API cũ hơn không có ViewPager.getCurrentItem().


Đầu tiên, một thông tin nhỏ. Nếu bạn lặp qua tất cả các con của một ViewPager ViewPager.getChildAt(x);và in ra với toString()(hoặc getLeft()) từng View con (một trang) và sau đó thực hiện việc này mỗi khi bạn thay đổi trang, bạn sẽ nhận thấy rằng các con sẽ không theo thứ tự logic mà chúng được hiển thị khi bạn bắt đầu quay lại các trang (phân trang lại từ đầu). Rõ ràng, nó sẽ xóa con không cần thiết khỏi mảng sau đó nối con mới nhất vào mảng. Vì vậy, ví dụ, giả sử bạn đang xem trang 2 sau đó chuyển thành trang 3, danh sách con của bạn sẽ theo thứ tự này page 2, page 3, page 4có nghĩa là ViewPager.getChildAt(1);sẽ trả về trang hiện tại. Tuy nhiên, nếu sau đó bạn chuyển về trang 2 (từ trang 3) thì danh sách con cái của bạn sẽ theo thứ tự page 2, page 3, page 1này có nghĩa làViewPager.getChildAt(1);không trả lại trang hiện tại. Tôi vẫn chưa thể tìm ra logic đơn giản để loại bỏ trang hiện tại bằng cách sử dụng thông tin này. Bởi vì thứ tự của các trang trong mảng phía sau getChildAttheo thứ tự tùy ý dựa trên cách người dùng phân trang xung quanh.

Điều đó đang được nói, tôi đã phát triển một công việc hack xung quanh. Tôi không có manh mối nào nếu chức năng này sẽ hoạt động trong tất cả các môi trường, nhưng nó hoạt động cho dự án hiện tại của tôi. Tôi sẽ nghi ngờ nếu không phải cho bạn, thì đó là vấn đề của cấp API khác. Nhưng tôi thực sự không nghi ngờ bất kỳ vấn đề nào đối với các môi trường khác.

Bây giờ, vào miếng thịt. Những gì tôi nhận thấy là kết quả của ViewPager.getChildAt(x).getLeft()sẽ có một số loại tọa độ pixel ngang liên quan đến gốc. Vì vậy, tôi đã sử dụng thông tin này để loại bỏ chế độ xem hiện tại.

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

Chức năng này có lẽ là một hack đáng ngờ vì nó dựa vào giá trị của getLeft()để tìm ra tất cả. Nhưng, tôi lấy tọa độ bên trái của mỗi đứa trẻ. Sau đó, tôi so sánh giá trị này với các giá trị khác và lưu trữ trang đầu tiên và trang thứ hai, trả lại trang thứ hai (trang hiện tại) ra khỏi hàm. Nó có vẻ hoạt động tốt.

Tại sao (bạn có thể hỏi) tôi không sử dụng onClickListenterhoặc bất kỳ giải pháp nào? Chà, tôi đã xác định rằng có một con đường thẳng tiến để thực hiện điều này mà không cần phải bao gồm người nghe, các tầng lớp khác, sự tập trung không thể thuyết phục và sự cồng kềnh khác. Thật không may, giải pháp này không chính xác về phía trước. Tuy nhiên, nó không làm mất đi sự cồng kềnh, các lớp khác và người nghe. Nếu tôi có thể tìm ra cách dễ dàng hơn, tôi sẽ viết lại hàm này. Hoặc có thể, điều này sẽ cung cấp cái nhìn sâu sắc để người khác có thể hiển linh.


1
Bạn đã cứu tôi! có một số lỗi ghê tởm. không thể tìm thấy những gì đã xảy ra. Bạn, thưa ông, xứng đáng nhận được bazi tỷ phiếu ủng hộ!
Nursultan Talapbekov

Cảm ơn các bạn! Tôi đoán cộng đồng không chia sẻ sự nhiệt tình của bạn.
Pimp Trizkit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.