Android: Notify Scrollview that it's child's size has changed: how?

14,461

I found a solution after trying just about every onXXX() method. onLayout can be used. You can plan the scroll and do it later in onLayout().

Extend your scrollview, and add:

private int onLayoutScrollByX = 0;
private int onLayoutScrollByY = 0;

public void planScrollBy(int x, int y) {
    onLayoutScrollByX += x;
    onLayoutScrollByY += y;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    doPlannedScroll();
}

public void doPlannedScroll() {
    if (onLayoutScrollByX != 0 || onLayoutScrollByY != 0) {
        scrollBy(onLayoutScrollByX, onLayoutScrollByY);
        onLayoutScrollByX = 0;
        onLayoutScrollByY = 0;
    }
}

Now, to use this in your code, instead of scrollBy(x,y) use planScrollBy(x,y). It will do the scroll at a time when the new size of the child is "known", but not displayed on screen yet.

When you use a horizontal or vertical scrollview, of course you can only scroll one way, so you will have to change this code it a bit (or not, but it will ignore the scroll on the other axis). I used a TwoDScrollView, you can find it on the web.

Share:
14,461
Frank
Author by

Frank

Updated on August 21, 2022

Comments

  • Frank
    Frank almost 2 years

    When I enlarge the size of the content of a scrollview, the scrollview takes a while to get to "know" this size change of it's child. How can I order the ScrollView to check it's child immediately?

    I have an ImageView in a LinearLayout in a ScrollView.

    In my ScaleListener.onScale, I change the size of my LinearLayout. I then try to order a scroll on the scrollview. In the ScaleListener.onScale:

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageView.getLayoutParams();
    params.width = (int) (startX * scaleFactor);
    params.height = (int) (startY * scaleFactor);
    imageView.setLayoutParams(params);
    
    (...)
    
    scrollView.scrollBy(scrollX, scrollY);
    

    However, no scrolling occurs when in the situation before the scaling scrolling was not possible because the view was too small to scroll. After the setLayoutParams, the view should be larger, but no scrolling occurs because the scrollview thinks the child is still small.

    When a fes ms later the onScroll is called again, it does scroll fine, it somehow found out that the child is larger and scrollable.

    How can I notify the scrollview immediately, that the child's size has changed? So that scrollBy will work right after setLayoutParams on it's child?