Scrollview vertical and horizontal in android Scrollview vertical and horizontal in android android android

Scrollview vertical and horizontal in android


Mixing some of the suggestions above, and was able to get a good solution:

Custom ScrollView:

package com.scrollable.view;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.ScrollView;public class VScroll extends ScrollView {    public VScroll(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public VScroll(Context context, AttributeSet attrs) {        super(context, attrs);    }    public VScroll(Context context) {        super(context);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        return false;    }}

Custom HorizontalScrollView:

package com.scrollable.view;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.HorizontalScrollView;public class HScroll extends HorizontalScrollView {    public HScroll(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public HScroll(Context context, AttributeSet attrs) {        super(context, attrs);    }    public HScroll(Context context) {        super(context);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        return false;    }}

the ScrollableImageActivity:

package com.scrollable.view;import android.app.Activity;import android.os.Bundle;import android.view.MotionEvent;import android.widget.HorizontalScrollView;import android.widget.ScrollView;public class ScrollableImageActivity extends Activity {    private float mx, my;    private float curX, curY;    private ScrollView vScroll;    private HorizontalScrollView hScroll;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        vScroll = (ScrollView) findViewById(R.id.vScroll);        hScroll = (HorizontalScrollView) findViewById(R.id.hScroll);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        float curX, curY;        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mx = event.getX();                my = event.getY();                break;            case MotionEvent.ACTION_MOVE:                curX = event.getX();                curY = event.getY();                vScroll.scrollBy((int) (mx - curX), (int) (my - curY));                hScroll.scrollBy((int) (mx - curX), (int) (my - curY));                mx = curX;                my = curY;                break;            case MotionEvent.ACTION_UP:                curX = event.getX();                curY = event.getY();                vScroll.scrollBy((int) (mx - curX), (int) (my - curY));                hScroll.scrollBy((int) (mx - curX), (int) (my - curY));                break;        }        return true;    }}

the layout:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="fill_parent"    android:layout_height="fill_parent">    <com.scrollable.view.VScroll android:layout_height="fill_parent"        android:layout_width="fill_parent" android:id="@+id/vScroll">        <com.scrollable.view.HScroll android:id="@+id/hScroll"            android:layout_width="fill_parent" android:layout_height="fill_parent">            <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/bg"></ImageView>        </com.scrollable.view.HScroll>    </com.scrollable.view.VScroll></LinearLayout>


Since this seems to be the first search result in Google for "Android vertical+horizontal ScrollView", I thought I should add this here. Matt Clark has built a custom view based on the Android source, and it seems to work perfectly: Two Dimensional ScrollView

Beware that the class in that page has a bug calculating the view's horizonal width. A fix by Manuel Hilty is in the comments:

Solution: Replace the statement on line 808 by the following:

final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);


Edit: The Link doesn't work anymore but here is a link to an old version of the blogpost.


I found a better solution.

XML: (design.xml)

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">  <FrameLayout android:layout_width="90px" android:layout_height="90px">    <RelativeLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent">            </RelativeLayout></FrameLayout></FrameLayout>

Java Code:

public class Example extends Activity {  private RelativeLayout container;  private int currentX;  private int currentY;  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.design);    container = (RelativeLayout)findViewById(R.id.container);    int top = 0;    int left = 0;    ImageView image1 = ...    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);    layoutParams.setMargins(left, top, 0, 0);                   container.addView(image1, layoutParams);    ImageView image2 = ...    left+= 100;    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);    layoutParams.setMargins(left, top, 0, 0);                   container.addView(image2, layoutParams);    ImageView image3 = ...    left= 0;    top+= 100;    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);    layoutParams.setMargins(left, top, 0, 0);                   container.addView(image3, layoutParams);    ImageView image4 = ...    left+= 100;         RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);    layoutParams.setMargins(left, top, 0, 0);                   container.addView(image4, layoutParams);  }       @Override   public boolean onTouchEvent(MotionEvent event) {    switch (event.getAction()) {        case MotionEvent.ACTION_DOWN: {            currentX = (int) event.getRawX();            currentY = (int) event.getRawY();            break;        }        case MotionEvent.ACTION_MOVE: {            int x2 = (int) event.getRawX();            int y2 = (int) event.getRawY();            container.scrollBy(currentX - x2 , currentY - y2);            currentX = x2;            currentY = y2;            break;        }           case MotionEvent.ACTION_UP: {            break;        }    }      return true;   }}

That's works!!!

If you want to load other layout or control, the structure is the same.