Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically scroll an HorizontalScrollView

I have an HorizontalScrollView which contains a RelativeLayout. This layout is empty in the XML, and is populated from java in the onCreate.

I would like this scroll view to be initially somewhere in the middle of the RelativeLayout, which is way larger than the screen.

I tried mHorizScrollView.scrollTo(offsetX, 0); which doesn't work. I don't know what's wrong with this.

I could post the code, but it is not really relevant. What matters is that everything is done programatically (has to :s), and that the initial position of the HorizontalScrollView has to be set programmatically.

Thanks for reading. Please tell me if you need more details or if this is not clear enough.

like image 422
Benoit Duffez Avatar asked Jan 25 '11 23:01

Benoit Duffez


6 Answers

I found that if you extend the HorizontalScrollView and override the onLayout, you can cleanly scroll, after the super call to 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: For scrolling to start or end you can use:

this.fullScroll(HorizontalScrollView.FOCUS_RIGHT/FOCUS_LEFT);

instead of

this.scrollTo(wherever, 0);
like image 177
HalR Avatar answered Oct 06 '22 00:10

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);
    }
like image 21
tekkavi Avatar answered Oct 05 '22 23:10

tekkavi


To test whether it's a timing issue (which I think it is), instead of calling scrollTo() in onStart, call postDelayed() with a Runnable that calls scrollTo, with a delay of 30 or so.

like image 31
Ted Hopp Avatar answered Oct 05 '22 23:10

Ted Hopp


A better approach would be using the ViewTreeObserver to observe layouts.

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
      }
    });
  }
}
like image 30
Vikram Bodicherla Avatar answered Oct 05 '22 22:10

Vikram Bodicherla


The problem is that the view doesn't have a size yet. The Clean way to do this is to implement the onSizeChanged of the ScrollView to send a message to a Handler in your activity to in order to notify the activity that the view has a size and that scrolling is possible.

like image 33
Alexandros Avatar answered Oct 06 '22 00:10

Alexandros


Use view.post and write scrollTo(x,y) inside run method. This the way to invalidate view in post method as per android API document.

like image 45
Piyush Avatar answered Oct 06 '22 00:10

Piyush