Scrolling a HorizontalScrollView by clicking buttons on its sides

user2181330 picture user2181330 · Apr 18, 2013 · Viewed 13.1k times · Source

I am using a HorizontalScrollView within a Fragment. When I scroll this view instead of scrolling the items within HorizontalScrollView the whole fragment is scrolled to either left or right. Now I have thought of using buttons on both sides of the layout. But cannot get how to scroll my scroll view on either side.

Any help in this regard will be highly appreciated.

EDIT

Following is my xml file.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<ImageButton
    android:id="@+id/btn_left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:src="@drawable/left_arrow" />

<ImageButton
    android:id="@+id/btn_right"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:src="@drawable/right_arrow" />

<HorizontalScrollView
    android:id="@+id/horizontal_scrollview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/btn_right"
    android:layout_toRightOf="@id/btn_left"
    android:fadeScrollbars="false"
    android:padding="5dp"
    android:scrollbarAlwaysDrawHorizontalTrack="true"
    android:scrollbars="horizontal" >

    <LinearLayout
        android:id="@+id/dynamic_generation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    </LinearLayout>
</HorizontalScrollView>

and my java file

public class MyGallery extends Activity {

private LinearLayout linearLayout;

private ImageButton leftBtn;
private ImageButton rightBtn;
private HorizontalScrollView hsv;
int currentScrollX = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.horizontalscrolling);

    leftBtn = (ImageButton) findViewById(R.id.btn_left);
    rightBtn = (ImageButton) findViewById(R.id.btn_right);
    hsv = (HorizontalScrollView) findViewById(R.id.horizontal_scrollview);
    linearLayout = (LinearLayout) findViewById(R.id.dynamic_generation);

    leftBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
        }
    });

    rightBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        }
    });

    String[] users = new String[20];
    for (int i = 0; i < 20; i++) {
        users[i] = "user " + (i + 1);
    }

    for (int i = 0; i < users.length; i++) {
        final TextView userId = new TextView(MyGallery.this);
        userId.setText(users[i]);
        ImageView imageView = new ImageView(MyGallery.this);
        linearLayout.addView(userId);
        linearLayout.addView(imageView);
        userId.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(MyGallery.this,
                        userId.getText() + " has been clicked!",
                        Toast.LENGTH_LONG).show();
                // hsv.
            }
        });
    }
}

}

What I need

When I press any of the left or right button scroll view must scroll to left or right respectively.

Answer

Catherine picture Catherine · Apr 18, 2013

If you add the following line of code to your existing handler, your view will scroll right with every button click:

rightBtn.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        hsv.scrollTo((int)hsv.getScrollX() + 10, (int)hsv.getScrollY());
    }
});

If you'd like it to scroll more smoothly you can use an onTouchListener instead:

rightBtn.setOnTouchListener(new View.OnTouchListener() {

    private Handler mHandler;
    private long mInitialDelay = 300;
    private long mRepeatDelay = 100;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mHandler != null)
                    return true;
                mHandler = new Handler();
                mHandler.postDelayed(mAction, mInitialDelay);
                break;
            case MotionEvent.ACTION_UP:
                if (mHandler == null)
                    return true;
                mHandler.removeCallbacks(mAction);
                mHandler = null;
                break;
        }
        return false;
    }

    Runnable mAction = new Runnable() {
        @Override
        public void run() {
            hsv.scrollTo((int) hsv.getScrollX() + 10, (int) hsv.getScrollY());
            mHandler.postDelayed(mAction, mRepeatDelay);
        }
    };
});

Vary the delays to your liking to get the smoothness and responsiveness you want.