Faites défiler par programme jusqu'à une position spécifique dans un ListView Android

157

Comment puis-je faire défiler par programme jusqu'à une position spécifique dans un ListView?

Par exemple, j'ai un String[] {A,B,C,D....}, et je dois définir l'élément le plus visible du ListViewsur l'index 21 de mon String[].

Maxime
la source
voir ma réponse ici, stackoverflow.com/a/29345217/1881527
Melbourne Lopes

Réponses:

386

Pour un défilement direct:

getListView().setSelection(21);

Pour un défilement fluide:

getListView().smoothScrollToPosition(21);
HandlerExploit
la source
Cool, c'est exactement ce que je veux!
jiasli
Super, très utile Cela me fait gagner du temps. Merci.
Neha Agarwal
Autre différence: le premier essaie de se placer au milieu de la liste.
Victor Pinto
11
smoothScrollToPositionne fonctionne pas, une suggestion?
SweetWisher ツ
1
@SweetWisher ツ essayez de poster retarder l'exécution, quelque chose comme:listView.post(() -> listView.smoothScrollToPosition());
Andy Res
64

Pour un SmoothScroll avec durée de défilement:

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

Paramètres
position -> Position à faire défiler jusqu'au
décalage ----> Distance souhaitée en pixels de position à partir du haut de la vue lorsque le défilement est terminé
durée-> Nombre de millisecondes à utiliser pour le défilement

Remarque: à partir de l'API 11.

La réponse de HandlerExploit était ce que je cherchais, mais ma liste est assez longue et aussi avec un défilement alphabétique. Ensuite, j'ai trouvé que la même fonction peut également prendre d'autres paramètres :)


Edit: (De la suggestion de l'AFD)

Pour positionner la sélection actuelle:

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

mListView.smoothScrollToPositionFromTop(position, h1/2 - h2/2, duration);  
amalBit
la source
Fonctionne très bien. Pour améliorer votre réponse, le décalage peut être calculé comme décrit sur stackoverflow.com/questions/5540223/...
AFD
qu'est-ce que v.getHeight ()?
Panache
@Panache v est la ligne de la liste
amalBit
i love youuuuuu
Joao Ferreira
10

Mettez votre code dans le gestionnaire comme suit,

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

puis appelez cette méthode comme,

timerDelayRunForScroll(100);

À VOTRE SANTÉ!!!

Melbourne Lopes
la source
7

J'ai défini OnGroupExpandListener et remplacer onGroupExpand () comme:

et utilisez la méthode setSelectionFromTop () qui définit l'élément sélectionné et positionne la sélection à y pixels à partir du bord supérieur de ListView. (S'il est en mode tactile, l'élément ne sera pas sélectionné mais il sera toujours positionné de manière appropriée.) (Android Docs)

    yourlist.setOnGroupExpandListener (new ExpandableListView.OnGroupExpandListener()
    {

        @Override
        public void onGroupExpand(int groupPosition) {

            expList.setSelectionFromTop(groupPosition, 0);
            //your other code
        }
    });
Inet Labs
la source
J'ai besoin de faire défiler une autre vue simultanément tout en faisant défiler la lisview. L'utilisation de setSelectionFromTop sur listview pour le défilement bloque le thread d'interface utilisateur, ce qui ralentit le défilement d'une autre vue. Pouvez-vous suggérer comment procéder?
VijayRaj
7

Le Listviewdéfilement sera positionné en haut par défaut, mais vous voulez faire défiler s'il n'est pas visible, utilisez ceci:

if (listView1.getFirstVisiblePosition() > position || listView1.getLastVisiblePosition() < position)
            listView1.setSelection(position);
Zalak Gajjar
la source
Merci @zalak Résolvez mon problème, abandonnez-vous
Mitul Bhadeshiya
5

Si quelqu'un recherche une fonctionnalité similaire comme l'application Gmail,

Le défilement Listview sera positionné en haut par défaut. Merci pour l'indice. amalBit. Il suffit de le soustraire. C'est tout.

 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
la source
4

Manipulation de la liste Afficher le défilement en utilisant UP / Down avec le bouton.

Si quelqu'un est intéressé par la gestion de la liste, affichez une ligne vers le haut / bas à l'aide du bouton puis.

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
la source
Je vous donne le vote juste parce que vous êtes le seul à avoir montré un moyen d'obtenir la position actuelle, mais vous devriez améliorer l'exemple.
Panciz
4

Si vous souhaitez accéder directement à la position souhaitée dans une liste, utilisez simplement

listView.setSelection (position int);

et si vous souhaitez passer en douceur à la position souhaitée dans listView, utilisez simplement

listView.smoothScrollToPosition (position int);

Vijay
la source
3

C'est ce qui a fonctionné pour moi. Combinaison de réponses par amalBit et 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); 
}

puis appelez cette méthode comme:

timerDelayRunForScroll(400);
Prasanna Ramaswamy
la source
1

sa sélection facile list-view.set (vous pos); ou vous pouvez enregistrer votre position avec sharedprefrenceand lorsque vous démarrez l'activité, il obtient les préférences et définit la suppression de cet int

Janatan
la source
tout ce que je voulais faire était de passer automatiquement en haut de la liste, sans aucune animation de défilement ... cela a parfaitement fonctionné pour cela
RH201
1

-Si vous voulez juste que la liste défile vers le haut \ dawn jusqu'à une position spécifique:

myListView.smoothScrollToPosition(i);

-si vous souhaitez obtenir la position d'un élément spécifique dans myListView:

myListView.getItemAtPosition(i);

-aussi cela myListView.getVerticalScrollbarPosition(i);peut vous aider.

Bonne chance :)

Basil Rawa
la source
0

Vous avez besoin de deux choses pour définir précisément la position de défilement d'une listView:

Pour obtenir la position actuelle du défilement de la liste:

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

Pour définir la position de défilement de listView:

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

J'ai trouvé cette solution pour permettre le défilement de haut en bas à l'aide de deux boutons différents.

Comme suggéré par @Nepster, j'implémente le défilement par programme en utilisant getFirstVisiblePosition () et getLastVisiblePosition () pour obtenir la position actuelle.

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
la source