6

how can I set scroll of scrollview to x pixels, before it's even shown?

In ScrollView I have some Views and i know that it will fill screen. Can I scroll to let say second View, so that first View is not visible when activity is started?

Now I have sth like this, but I think it's not perfect, sometimes, I see first View, and then it's scrolled to the second one

@Override
public void onGlobalLayout() {
    if (mHorizontalScrollView.getChildCount() > 0 && mHorizontalScrollView.getChildAt(0).getWidth() > mScreenWidth) {
            hsv.scrollTo(100, 0);
    }
}

EDIT!!

Second attempt was to use http://developer.android.com/reference/android/view/ViewTreeObserver.OnPreDrawListener.html instead of http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html In OnPreDrawListener we can read that At this point, all views in the tree have been measured and given a frame. Clients can use this to adjust their scroll bounds or even to request a new layout before drawing occurs. so basically at this point we should adjust scrolling. So I created:

@Override
public boolean onPreDraw() {
    if (hsv.getChildCount() > 0 && hsv.getChildAt(0).getWidth() > mScreenWidth) {
        hsv.scrollTo(100, 0);
        return false;
    }
    return true;
}

but now it's never working for me.

Mikooos
  • 5,360
  • 5
  • 31
  • 45

6 Answers6

2

I combined onGlobalLayout with code below. It's not so great to use that hack but it still quite efficient. When I get onGlobalLayout event I check if layouts are done and then if it's ok I use method below.

// hsv - horizontal scroll view
private void forceShowColumn(final int column) {
    int scrollTo = childViewWidth * column;
    if (scrollTo == hsv.getScrollX()) {
        return;
    }
    hsv.scrollTo(scrollTo, 0);

    hsv.postDelayed(new Runnable() {

        @Override
        public void run() {
            forceShowColumn(column);
        }
    }, 10);
}
Mikooos
  • 5,360
  • 5
  • 31
  • 45
1

I solved this issue by implementing View.OnLayoutChangeListener in the fragment that controls my ScrollView.

public class YourFragment extends Fragment implements View.OnLayoutChangeListener{

...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.your_fragment_layout, container, false);

    //set scrollview layout change listener to be handled in this fragment
    sv = (ScrollView) view.findViewById(R.id.your_scroll_view);
    sv.addOnLayoutChangeListener(this);

    return view;
}

...

public void onLayoutChange (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom){
    switch (v.getId())
    {
        case R.id.your_scroll_view:
        {
                sv.scrollTo(0, sv.getTop());
        }
    }
}
sspaniel
  • 647
  • 3
  • 10
1

try View.post(Runnable) in onCreate-method.

hauns
  • 116
  • 1
  • 6
0

MrJre gives the most elegant solution: "override onLayout() in the scrollview and do it there after super.onLayout()"

Example code here:

https://stackoverflow.com/a/10209457/1310343

Community
  • 1
  • 1
Frank
  • 12,010
  • 8
  • 61
  • 78
0

The correct way to do this, is to call scrollTo() on the ScrollView after the view has been through its measurement and layout passes, otherwise the width of the content in the scrollView will be 0, and thus scrollTo() will not scroll to the right position. Usually after the constructor has been called and after the view has been added to its parent.

See http://developer.android.com/guide/topics/ui/how-android-draws.html for more insight on how android draws views.

MrJre
  • 7,082
  • 7
  • 53
  • 66
  • As you see I my code, I check if scrollview child width is set. So is there another way to check if I can scroll? I also use http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html maybe I should use http://developer.android.com/reference/android/view/ViewTreeObserver.OnPreDrawListener.html ? – Mikooos Aug 18 '11 at 10:21
  • one other possibility is to override onLayout() in the scrollview and do it there after super.onLayout() – MrJre Aug 18 '11 at 11:18
  • Yeah, I used to do that, but still it's not working every time, sometimes screen blinks. In OnLayout I even checked if sizes are set. – Mikooos Aug 18 '11 at 11:42
-1

Use :

scrollTo (int x, int y)

It sets the scrolled position of your view. This will cause a call to onScrollChanged

For more details : see this

ScrollView ScrollTo

Uday
  • 5,933
  • 9
  • 44
  • 76