web-dev-qa-db-fra.com

Comment faire défiler par programme un HorizontalScrollView

J'ai un HorizontalScrollView qui contient un RelativeLayout. Cette disposition est vide dans le XML et est renseignée à partir de Java dans onCreate.

Je voudrais que cette vue de défilement soit initialement quelque part au milieu de la RelativeLayout, qui est bien plus grande que l'écran.

J'ai essayé mHorizScrollView.scrollTo(offsetX, 0); qui ne fonctionne pas. Je ne sais pas ce qui ne va pas.

Je pourrais poster le code, mais ce n'est pas vraiment pertinent. Ce qui compte, c’est que tout se fasse de manière programmée (doit: s) et que la position initiale de HorizontalScrollView doit être définie par programme.

Merci d'avoir lu. S'il vous plaît dites-moi si vous avez besoin de plus de détails ou si ce n'est pas assez clair.

21
Benoit Duffez

J'ai trouvé que si vous extend la HorizontalScrollView et remplaciez la onLayout, vous pouvez faire défiler proprement, après le super appel à onLayout:

MyScrollView extends HorizontalScrollView {
    protected void onLayout (boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        this.scrollTo(wherever, 0);
    }
}

EDIT: Pour passer à start ou end vous pouvez utiliser:

this.fullScroll(HorizontalScrollView.FOCUS_RIGHT/FOCUS_LEFT);

au lieu de 

this.scrollTo(wherever, 0);
26
HalR
public void autoSmoothScroll() {

        final HorizontalScrollView hsv = (HorizontalScrollView) view.findViewById(R.id.horiscroll);
        hsv.postDelayed(new Runnable() {
            @Override
            public void run() {
                //hsv.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
                hsv.smoothScrollBy(500, 0);
            }
        },100);
    }
24
tekkavi

Pour vérifier s’il s’agit d’un problème de synchronisation (ce que je pense que c’est), au lieu d’appeler scrollTo () dans onStart, appelez postDelayed () avec un Runnable qui appelle scrollTo, avec un délai de 30 secondes environ.

16
Ted Hopp

Une meilleure approche consisterait à utiliser la variable ViewTreeObserver pour observer les dispositions.

View interestedInView;
onCreate(){
  //Code

  //Observe for a layout change
  ViewTreeObserver viewTreeObserver = interestedInView.getViewTreeObserver();
  if (viewTreeObserver.isAlive()) {
    viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        //REMOVE THE VIEWTREE OBSERVER
        //interestedInView is ready for size and position queries because it has been laid out
      }
    });
  }
}
9
Vikram Bodicherla

Le problème est que la vue n'a pas encore de taille. Pour ce faire, la méthode Clean consiste à implémenter onSizeChanged de ScrollView pour envoyer un message à un gestionnaire de votre activité afin de notifier à l'activité que la vue a une taille et que le défilement est possible. 

1
Alexandros

Utilisez view.post et écrivez scrollTo (x, y) dans la méthode run. Ceci permet d'invalider l'affichage de la méthode de publication conformément au document de l'API Android.

1
Piyush

La fonction scrollTo devrait fonctionner. Quelle est la layout_width du HSV et la vue qu'il contient?

0
Jason LeBrun

La fonction onSizeChanged devrait fonctionner. Ce que vous ne comprenez pas, c'est que onSizeChanged devrait envoyer un message à un gestionnaire de votre activité et non à une fonction de rappel, car un gestionnaire exécutera le code dans le thread d'interface utilisateur. Vous ne pouvez pas effectuer d'opérations d'interface utilisateur en dehors de celui-ci. Jetez un coup d'œil aux manutentionnaires.

0