Get child location in HorizontalScrollView and scroll to it

ali picture ali · Mar 5, 2013 · Viewed 13.7k times · Source

Looks like I can't get or set any position or scrolling amount in my simple layout:

// Relative layout - main_layout
<HorizontalScrollView
    android:id="@+id/MenuScroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:fillViewport="true"
    android:scrollbars="none" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:orientation="horizontal"
        android:layout_gravity="center"
        android:padding="0dp" >

        <Button
            android:id="@+id/button1"
            android:layout_width="150dp"
            android:layout_height="fill_parent" />

        <Button
            android:id="@+id/button2"
            android:layout_width="150dp"
            android:layout_height="fill_parent" />

        <Button
            android:id="@+id/button3"
            android:layout_width="150dp"
            android:layout_height="fill_parent" />

        <Button
            android:id="@+id/button4"
            android:layout_width="150dp"
            android:layout_height="fill_parent" />

        <Button
            android:id="@+id/button5"
            android:layout_width="150dp"
            android:layout_height="fill_parent" />

    </LinearLayout>
</HorizontalScrollView>
// End of RelativeLayout - main_layout

What I want in my MainActivity is to get the position of any button inside the HorizontalScrollView and scroll to that position. At the moment I can't get the left value (it's always 0) and if I try to scrollTo the HorizontalScrollView it just doesn't, regardless of what the value for x or y is.

// imports
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main_layout);

        final Button button3 = (Button)findViewById(R.id.button3);
        Rect rectf = new Rect();
        button3.getLocalVisibleRect(rectf);
        Log.i("Left: ", String.valueOf(rectf.left)); // it is always 0

        HorizontalScrollView MenuScroll = (HorizontalScrollView)findViewById(R.id.MenuScroll);
        // Trying to scroll to X=100 but it doesn't
        MenuScroll.scrollTo(100, MenuScroll.getBottom());
    }
}

So, as I said, I can't get the left position for my button and either can scroll to some X position in my HorizontalScrollView. Is this possible?

Answer

user picture user · Mar 5, 2013

(it's always 0)

Keep in mind that the views don't have dimensions in the onCreate method as they are placed on the screen after the onCreate callback returns.

What I want in my MainActivity is to get the position of any button inside the HorizontalScrollView and scroll to that position.

Have a look at the code below(placed in the onCreate method):

    final HorizontalScrollView MenuScroll = (HorizontalScrollView) findViewById(R.id.MenuScroll);

    MenuScroll.post(new Runnable() {

        @Override
        public void run() {
            final Button button3 = (Button) findViewById(R.id.button3);
            int scrollTo = 0;
            final int count = ((LinearLayout) MenuScroll.getChildAt(0))
                    .getChildCount();
            for (int i = 0; i < count; i++) {
                final View child = ((LinearLayout) MenuScroll.getChildAt(0))
                        .getChildAt(i);                 
                if (child != button3) {
                    scrollTo += child.getWidth();
                } else {
                    break;
                }
            }
            MenuScroll.scrollTo(scrollTo, 0);
        }

    });

Also be careful with the attributes you use in the layout(I'm referring to the layout_gravity which could cause problems if I'm not mistaken).