Получение текущей позиции ViewPager

84

Я знаю, что с помощью виджета "Галерея" я смог использовать getSelectedItemPosition (); чтобы получить текущую позицию, но, похоже, ViewPager не имеет ее.

Я знаю, что могу настроить слушателя и получить позицию при переключении страницы. Но мне нужна текущая позиция просмотра.

Адам
источник

Ответы:

94

Создайте слушателя и установите его на вашем окне просмотра:

/**
 * 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;
    }
}
androidu
источник
4
Просто имейте в виду, когда используете это: getCurrentPage () всегда будет возвращать 0, если представление никогда не менялось. По какой-то причине, если вы входите в ViewPager в каком-либо представлении, отличном от первого представления, ожидаемое значение не должно быть 0 ... У меня просто возникла проблема с этим, поскольку я не всегда входил в представление в первом представлении Посмотреть.
Брэндон Романо
1
@ Адам, пожалуйста, скажите мне, как вызвать эту функцию getCurrentPage
user3233280
Все очень просто. Спасибо androidu.
whdals0
193

Вы можете использовать:

mViewPager.getCurrentItem()
Терри
источник
В ViewPager нет метода getCurrentItem
Дмитрий Гусельников
3
Простите, я ошибся. Только что обновил мою библиотеку поддержки, и этот метод существует в новой версии
Дмитрий Гусельников
4

Обновление 2019

Теперь вы можете настроить addOnPageChangeListenerView 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

Я говорю вам, что это взлом, так что нет причин понижать голос по этой причине. То есть будет либо полезно конкретно вам, либо нет. В любом случае приведенное ниже описание даст некоторое представление и будет полезно сообществу. Кроме того, это решение подходит для старых API, которых нет ViewPager.getCurrentItem().


Для начала немного информации. Если вы перебираете всех дочерних элементов ViewPager ViewPager.getChildAt(x);и распечатываете с toString()(или getLeft()) каждым дочерним View (страницей), а затем делаете это каждый раз, когда вы меняете страницы, вы заметите, что дочерние элементы не будут находиться в том логическом порядке, в котором они отображаются в, когда вы начинаете переходить на предыдущие страницы (перелистывание назад к началу). Очевидно, он удалит ненужный дочерний элемент из массива, а затем добавит в массив самый новый дочерний элемент. Так, например, предположим, что вы смотрите на страницу 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
вы спасли меня! была какая-то ужасная ошибка. не мог найти, что пошло не так. Вы, сэр, заслуживаете миллиарда голосов!
Нурсултан Талапбеков 05
Спасибо, господа! Думаю, сообщество не разделяет вашего энтузиазма.
Pimp Trizkit