Obtendo a posição atual de um ViewPager

84

Eu sei que com o widget Gallery, consegui usar getSelectedItemPosition (); para recuperar a posição atual, no entanto, não parece que o ViewPager tenha isso.

Eu sei que posso configurar um ouvinte e recuperar a posição quando a página é trocada. Mas eu quero a posição de visualização atual.

Adão
fonte

Respostas:

94

Crie um listener e defina-o em seu 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;
    }
}
androidu
fonte
4
Esteja ciente ao usar isto: getCurrentPage () sempre retornará 0 quando a visualização nunca tiver sido alterada. Por algum motivo, se você entrar no ViewPager em alguma visualização diferente da primeira, o valor que você esperaria não deve ser 0 ... Acabei de ter um problema com isso, pois nem sempre entrei na visualização na primeira Visão.
Brandon Romano
1
@Adam pode me dizer como chamar esta função getCurrentPage
user3233280
É muito simples. Obrigado, androidu.
whdals0
193

Você pode usar:

mViewPager.getCurrentItem()
Terry
fonte
Não há método getCurrentItem no ViewPager
Dmitry Guselnikov
3
Desculpa eu estava errado. Acabei de atualizar minha biblioteca de suporte e este método existe em uma nova versão
Dmitry Guselnikov
4

Atualização 2019

Agora você pode definir addOnPageChangeListenerem Exibir pager para observar a mudança na posição da página.

Já que você queria configurar um ouvinte e recuperar a posição quando a página for trocada

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)
            }
        })
Hitesh Sahu
fonte
0

Estou dizendo que agora é um hack, então não há razão para downvote por esse motivo. Ou seja, será útil para você especificamente ou não. De qualquer forma, a descrição abaixo fornecerá alguns insights e será útil para a comunidade. Além disso, essa solução é boa para APIs mais antigas que não têm ViewPager.getCurrentItem().


Primeiro, algumas informações. Se você iterar através de todos os filhos de um ViewPager com ViewPager.getChildAt(x);e imprimir com toString()(ou getLeft()) cada Visualização filho (uma página) e, em seguida, fazer isso toda vez que mudar de página, você notará que os filhos não estarão na ordem lógica em que são exibidos quando você começa a voltar às páginas (voltar ao início). Aparentemente, ele removerá o filho desnecessário do array e, em seguida, acrescentará o filho mais novo ao array. Então, por exemplo, digamos que você está olhando a página 2 e depois mudou para a página 3, sua lista de filhos estará nesta ordem em uma ordem arbitrária com base em como o usuário está navegando.page 2, page 3, page 4 o que significa que ViewPager.getChildAt(1);retornará a página atual. Mas, se você voltar para a página 2 (da página 3), sua lista de crianças estará nesta ordem, o page 2, page 3, page 1que significa queViewPager.getChildAt(1);não retorna a página atual. Ainda não consegui encontrar uma lógica simples para eliminar a página atual usando essas informações. Porque a ordem das páginas na matriz posterior as páginasgetChildAt

Dito isso, desenvolvi uma solução alternativa para o hack. Não tenho ideia se esta função funcionará em todos os ambientes, mas funciona para meu projeto atual. Eu suspeitaria se não fosse para você, então é um problema de nível de API diferente. Mas eu realmente não suspeito de quaisquer problemas para outros ambientes.

Agora, para a carne. O que percebi é que o resultado de ViewPager.getChildAt(x).getLeft()terá algum tipo de coordenada de pixel horizontal em relação ao pai. Portanto, usei essas informações para descartar qual visualização é a atual.

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

Esta função é provavelmente um hack questionável porque depende do valor de getLeft() para descobrir tudo. Mas, eu pego a coordenada esquerda de cada criança. Em seguida, comparo isso com os outros valores e armazeno a primeira e a segunda páginas, retornando a segunda página (página atual) fora da função. Parece funcionar lindamente.

Por que (você pode perguntar) eu simplesmente não usei onClickListenterou qualquer outra solução? Bem, eu estava determinado que havia uma maneira direta de fazer isso sem ter que incluir ouvintes, outras classes, foco inconclusivo e outros inchaços. Infelizmente, essa solução não é exatamente direta. Mas, ele acaba com o inchaço, outras classes e ouvintes. Se eu conseguir descobrir uma maneira mais direta, estarei reescrevendo esta função. Ou talvez, isso proporcionará uma visão para outra pessoa ter uma epifania.

Pimp Trizkit
fonte
1
você me salvou! tinha algum bug horrível. não consegui encontrar o que estava errado. Você, senhor, merece um bazilhão de votos positivos!
Nursultan Talapbekov
Obrigado senhores! Acho que a comunidade não compartilha do seu entusiasmo.
Pimp Trizkit