I have a vertical ScrollView (actually, a custom ScrollView, code below) within a ViewFlipper. The ViewFlipper works fine unless I swipe horizantally over the ScrollView to flip to the previous/next view. The ScrollView itself works correctly.
Here's the design. The green box is the ScrollView, which should be vertical.
Here's the ScrollView:
public class SCScrollView extends ScrollView {
private float xDistance, yDistance, lastX, lastY;
GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());
OnTouchListener gestureListener;
public SCScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
gestureListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = ev.getX();
lastY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if(xDistance > yDistance)
return false;
}
return false;
//return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return gestureDetector.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
gestureDetector.onTouchEvent(ev);
super.dispatchTouchEvent(ev);
return true;
}
/** GestureDetector used to swipe between classes */
class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
}
I've been trying to base the solution on the advice here HorizontalScrollView within ScrollView Touch Handling and here Swipe/Fling tab-changing in conjunction with ScrollView? but regardless of what I return from the callbacks, I cannot get the ViewFlipper to see the fling across the ScrollView and frankly, I'm getting lost in the chain of touch and gesture listeners.
Any thoughts?
Thanks
As in the documented said
http://developer.android.com/reference/android/widget/ScrollView.html
ScrollView only supports vertical scrolling. For horizontal scrolling, use HorizontalScrollView.
So, I need to ask why did you really want to use your custom scrollview?
If you only intend to be able to scroll, you might no need to use it
only RelativeLayout.scrollBy(x,y); is enough
You could look at this link
Scrollview vertical and horizontal in android
Ok, So you need to make the gesture detect the fling over the ScrollView.
You could make it in your Activity without making custom ScrollView also
first, you need to
implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener
and in your class create gestureDetector
gd = new GestureDetector(this);
and your ScrollView object, just declared
sv.setOnTouchListener(this);
then, in override onTouch method
@Override
public boolean onTouch(View v, MotionEvent event) {
onTouchEvent(event); // throw to onTouchEvent
return false;
}
and in override onTouchEvent method
@Override
public boolean onTouchEvent(MotionEvent me)
{
return gd.onTouchEvent(me); // gd = gesturedetector
}
now override your onFling method like this
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// "Left Swipe"
vf.showPrevious(); // vf = ViewFlipper
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
// "Right Swipe"
vf.showNext();
}
return false;
}
and this is the whole code
ViewFlipperActivity class
import android.os.Bundle;
import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnTouchListener;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
public class ViewFlipperActivity extends Activity implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener
{
TextView tv;
GestureDetector gd;
ScrollView sv;
ViewFlipper vf;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gd = new GestureDetector(this);
setContentView(R.layout.activity_viewflipper);
tv = (TextView)findViewById(R.id.textView1);
sv = (ScrollView)findViewById(R.id.scrollView1);
vf = (ViewFlipper)findViewById(R.id.viewFlipper1);
sv.setOnTouchListener(this);
}
@Override
public boolean onDoubleTap(MotionEvent arg0) {
tv.setText("double tap");
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent arg0) {
tv.setText("double tap event");
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent arg0) {
tv.setText("single tap confirm");
return false;
}
@Override
public boolean onTouchEvent(MotionEvent me)
{
return gd.onTouchEvent(me);
}
@Override
public boolean onDown(MotionEvent arg0) {
tv.setText("down");
return false;
}
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
tv.setText("Left Swipe");
vf.showPrevious();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
tv.setText("Right Swipe");
vf.showNext();
}
return false;
}
@Override
public void onLongPress(MotionEvent arg0) {
tv.setText("long press");
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
tv.setText("scroll");
return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
tv.setText("show press");
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
tv.setText("single tab up");
return false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
onTouchEvent(event);
return false;
}
}
and activity_viewflipper.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="TextView" />
<ViewFlipper
android:id="@+id/viewFlipper1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/textView1" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/textView3"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="28dp"
android:layout_marginTop="63dp"
android:layout_toLeftOf="@+id/textView2" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="matrix"
android:src="@drawable/thailandmap" />
</ScrollView>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/scrollView1"
android:layout_marginRight="30dp"
android:text="TextView" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/scrollView1"
android:layout_marginBottom="250dp"
android:layout_marginRight="29dp"
android:text="TextView" />
</RelativeLayout>
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="matrix"
android:src="@drawable/thwriting" />
</ViewFlipper>
</RelativeLayout>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With