无法使ViewFlipper中的ScrollView上的水平投掷冒泡

时间:2012-09-21 10:45:16

标签: android

我在ViewFlipper中有一个垂直的ScrollView(实际上是一个自定义的ScrollView,代码如下)。除非我在ScrollView上水平滑动以翻转到上一个/下一个视图,否则ViewFlipper工作正常。 ScrollView本身可以正常工作。

这是设计。绿色框是ScrollView,它应该是垂直的。

enter image description here

这是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;
       }
    }

 }

我一直在努力将解决方案建立在HorizontalScrollView within ScrollView Touch HandlingSwipe/Fling tab-changing in conjunction with ScrollView?的建议基础上,但无论我从回调中返回什么,我都无法让ViewFlipper看到ScrollView上的信息而且坦率地说,我迷失在触摸和手势听众的链条中。

有什么想法吗?

由于

1 个答案:

答案 0 :(得分:6)

如记录所述

http://developer.android.com/reference/android/widget/ScrollView.html

  

ScrollView仅支持垂直滚动。对于水平滚动,   使用Horizo​​ntalScrollView。

所以,我需要问一下你为什么真的想要使用你的自定义滚动视图?

如果您只想滚动,则可能不需要使用它

只有RelativeLayout.scrollBy(x,y);

您可以查看此链接

Scrollview vertical and horizontal in android

修改

好的,所以你需要让手势检测ScrollView上的投掷。

你可以在你的Activity中创建它而不需要自定义ScrollView

首先,你需要

implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener

并在您的班级中创建gestureDetector

gd = new GestureDetector(this);

和您的ScrollView对象,刚刚声明

sv.setOnTouchListener(this);

然后,在覆盖onTouch方法

@Override
public boolean onTouch(View v, MotionEvent event) {
        onTouchEvent(event); // throw to onTouchEvent

    return false;
}

并覆盖onTouchEvent方法

@Override
public boolean onTouchEvent(MotionEvent me)
{
    return gd.onTouchEvent(me); // gd = gesturedetector
}

现在覆盖你的onFling方法,就像这样

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;
}

这是整个代码

ViewFlipperActivity类

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;
    }
}

和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>