Role programaticamente para uma posição específica em um Android ListView

157

Como posso rolar programaticamente para uma posição específica em um ListView?

Por exemplo, eu tenho um String[] {A,B,C,D....}e preciso definir o item visível no topo ListViewdo índice 21 do meu String[].

Maxime
fonte
possível duplicação de É possível rolar o ListView para o elemento filho de uma listrow?
David Snabel-Caunt 26/09
veja a minha resposta aqui, stackoverflow.com/a/29345217/1881527
Melbourne Lopes

Respostas:

386

Para uma rolagem direta:

getListView().setSelection(21);

Para uma rolagem suave:

getListView().smoothScrollToPosition(21);
HandlerExploit
fonte
Legal, é exatamente isso que eu quero!
jiasli
Ótimo, muito útil. Economize meu tempo. Obrigado.
Neha Agarwal
Outra diferença: o primeiro tenta definir no meio da lista.
Victor Pinto
11
smoothScrollToPositionnão está funcionando, alguma sugestão?
SweetWisherツ
1
@SweetWisherツtentar atraso pós a execução, algo como:listView.post(() -> listView.smoothScrollToPosition());
Andy Res
64

Para um SmoothScroll com duração de rolagem:

getListView().smoothScrollToPositionFromTop(position,offset,duration);

Parâmetros
position -> Position to scroll to
offset ----> Distância desejada em pixels de posição a partir do topo da vista quando a rolagem termina -
> Número de milissegundos a serem usados ​​na rolagem

Nota: da API 11.

A resposta de HandlerExploit foi o que eu estava procurando, mas Minha lista de exibição é bastante longa e também com o scroller de alfabeto. Então eu descobri que a mesma função pode ter outros parâmetros também :)


Editar: (por sugestão dos AFDs)

Para posicionar a seleção atual:

int h1 = mListView.getHeight();
int h2 = listViewRow.getHeight();

mListView.smoothScrollToPositionFromTop(position, h1/2 - h2/2, duration);  
amalBit
fonte
Funciona bem. Para melhorar sua resposta, o deslocamento pode ser calculado como descrito em stackoverflow.com/questions/5540223/…
AFD
o que é v.getHeight ()?
Panache
@Panache v é a linha da listview
amalBit
eu amo youuuuuu
Joao Ferreira
10

Coloque seu código no manipulador da seguinte maneira:

public void timerDelayRunForScroll(long time) {
        Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() {           
            public void run() {   
                try {
                    lstView.smoothScrollToPosition(YOUR_POSITION);
                } catch (Exception e) {}
            }
        }, time); 
    }

e depois chame esse método como,

timerDelayRunForScroll(100);

FELICIDADES!!!

Melbourne Lopes
fonte
7

Eu configurei OnGroupExpandListener e substitui onGroupExpand () como:

e use o método setSelectionFromTop () que define o item selecionado e posiciona a seleção y pixels da borda superior do ListView. (Se estiver no modo de toque, o item não será selecionado, mas ainda será posicionado adequadamente.) (Android docs)

    yourlist.setOnGroupExpandListener (new ExpandableListView.OnGroupExpandListener()
    {

        @Override
        public void onGroupExpand(int groupPosition) {

            expList.setSelectionFromTop(groupPosition, 0);
            //your other code
        }
    });
Inet Labs
fonte
Preciso rolar outra visualização simultaneamente enquanto estiver rolando o lisview. O uso de setSelectionFromTop na visualização de lista para rolagem bloqueia o encadeamento da interface do usuário, o que torna a rolagem de outra visualização lenta. Você pode dar alguma sugestão de como fazê-lo?
Vijayraj
7

A Listviewrolagem será posicionada no topo por padrão, mas deseja rolar se não estiver visível, use o seguinte:

if (listView1.getFirstVisiblePosition() > position || listView1.getLastVisiblePosition() < position)
            listView1.setSelection(position);
Zalak Gajjar
fonte
Graças @zalak resolver o meu problema, desistir de você
Mitul Bhadeshiya
5

Se alguém que procura uma funcionalidade semelhante, como o aplicativo Gmail,

A rolagem do Listview será posicionada no topo por padrão. Obrigado pela dica. amalBit. Apenas subtraia. É isso aí.

 Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            int h1 = mDrawerList.getHeight();
            int h2 = header.getHeight();
            mDrawerList.smoothScrollToPosition(h2-h1);
        }
    }, 1000);
EngineSense
fonte
4

Veja a rolagem usando UP / Down using.button

Se alguém estiver interessado em lidar com a listaVista uma linha para cima / para baixo usando o botão então.

public View.OnClickListener onChk = new View.OnClickListener() {
             public void onClick(View v) {

                 int index = list.getFirstVisiblePosition();
                 getListView().smoothScrollToPosition(index+1); // For increment. 

}
});
Zar E Ahmer
fonte
Dou-lhe o voto positivo apenas porque você é o único que mostrou uma maneira de obter a posição atual, mas você deve melhorar o exemplo.
Panciz
4

Se você quiser pular diretamente para a posição desejada em uma lista, basta usar

listView.setSelection (int position);

e se você quiser pular suavemente para a posição desejada no listView, use

listView.smoothScrollToPosition (int position);

Vijay
fonte
3

Isto é o que funcionou para mim. Combinação de respostas por amalBit & Melbourne Lopes

public void timerDelayRunForScroll(long time) {
    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() {           
        public void run() {   
            try {
                  int h1 = mListView.getHeight();
                  int h2 = v.getHeight();

                  mListView.smoothScrollToPositionFromTop(YOUR_POSITION, h1/2 - h2/2, 500);  

            } catch (Exception e) {}
        }
    }, time); 
}

e chame esse método como:

timerDelayRunForScroll(400);
Prasanna Ramaswamy
fonte
1

sua fácil seleção list-view.set (você pos); ou você pode salvar sua posição com prioridade compartilhada e, ao iniciar a atividade, ela obtém preferências e elegibilidade para esse int

janatan
fonte
tudo o que eu queria fazer era passar automaticamente para o topo da lista, sem nenhuma animação de rolagem ... isso funcionou perfeitamente para isso #
RH201
1

-Se você quiser que a lista role para cima \ amanhecer para uma posição específica:

myListView.smoothScrollToPosition(i);

-se você deseja obter a posição de um item específico no myListView:

myListView.getItemAtPosition(i);

-Também isso myListView.getVerticalScrollbarPosition(i);pode ajudá-lo.

Boa sorte :)

Basil Rawa
fonte
0

Você precisa de duas coisas para definir com precisão a posição de rolagem de um listView:

Para obter a posição atual do ScrollView da lista:

int firstVisiblePosition = listView.getFirstVisiblePosition(); 
int topEdge=listView.getChildAt(0).getTop(); //This gives how much the top view has been scrolled.

Para definir a posição de rolagem listView:

listView.setSelectionFromTop(firstVisiblePosition,0);
// Note the '-' sign for scrollTo.. 
listView.scrollTo(0,-topEdge);
Rahul Ogale
fonte
-1

Encontrei esta solução para permitir a rolagem para cima e para baixo usando dois botões diferentes.

Conforme sugerido por @Nepster, implementei a rolagem programaticamente usando getFirstVisiblePosition () e getLastVisiblePosition () para obter a posição atual.

final ListView lwresult = (ListView) findViewById(R.id.rds_rdi_mat_list);
    .....

        if (list.size() > 0) {
            ImageButton bnt = (ImageButton) findViewById(R.id.down_action);
            bnt.setVisibility(View.VISIBLE);
            bnt.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(lwresult.getLastVisiblePosition()<lwresult.getAdapter().getCount()){
                        lwresult.smoothScrollToPosition(lwresult.getLastVisiblePosition()+5);
                    }else{
                        lwresult.smoothScrollToPosition(lwresult.getAdapter().getCount());

                    }
                }
            });
            bnt = (ImageButton) findViewById(R.id.up_action);
            bnt.setVisibility(View.VISIBLE);

            bnt.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(lwresult.getFirstVisiblePosition()>0){
                        lwresult.smoothScrollToPosition(lwresult.getFirstVisiblePosition()-5);
                    }else{
                        lwresult.smoothScrollToPosition(0);
                    }

                }
            });
        }
Panciz
fonte