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

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

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

Ответ 1

Создайте слушателя и установите его на вашем 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;
    }
}

Ответ 2

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

mViewPager.getCurrentItem()

Ответ 3

Обновление 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)
            }
        })

Ответ 4

Я говорю вам, что это взлом, так что нет причин понижать голос по этой причине. Это значит, что это будет полезно для вас или нет. В любом случае, описание ниже предоставит некоторую информацию и будет полезным для сообщества. Кроме того, это решение подходит для более старых API, которые не имеют 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 или какое-либо onClickListenter решение? Ну, я был чертовски уверен, что есть прямой способ сделать это без необходимости включать слушателей, другие классы, неокончательный фокус и другие раздувания. К сожалению, это решение не совсем прямое. Но это избавляет от раздувания, других классов и слушателей. Если я смогу найти более прямой путь, я переписываю эту функцию. Или, может быть, это даст понимание для кого-то другого, чтобы иметь прозрение.