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[].



Respostas:


386

Para uma rolagem direta:

getListView().setSelection(21);

Para uma rolagem suave:

getListView().smoothScrollToPosition(21);

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

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!!!


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

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

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

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. 

}
});

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


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

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


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


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

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

                }
            });
        }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.