【问题标题】:Implementing swipes left/right in ScrollView在 ScrollView 中实现向左/向右滑动
【发布时间】:2013-12-13 00:43:47
【问题描述】:

我想向 ScrollView 添加滑动功能(从左到右),但不拦截所有触摸事件,这样子按钮仍然可以点击。

我像这样在滚动视图中添加了触摸监听器:

this.getView().findViewById(R.id.scrollView1).setOnTouchListener(new OnSwipeTouchListener() {
            public void onSwipeTop() {
                Toast.makeText(DetailFragment.this.getActivity(), "top", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeRight() {
                Toast.makeText(DetailFragment.this.getActivity(), "right", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeLeft() {
                Toast.makeText(DetailFragment.this.getActivity(), "left", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeBottom() {
                Toast.makeText(DetailFragment.this.getActivity(), "bottom", Toast.LENGTH_SHORT).show();
            }
        });

如果我让它保持原样,那么我的触摸监听器将永远不会被调用。所以我不得不继承ScrollView并覆盖onInterceptTouchEvent,这样滚动视图就会决定它想要拦截哪些触摸事件:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    boolean intercept = false;
    final int action = ev.getAction();
    ViewConfiguration vc = ViewConfiguration.get(this.getContext());
    int slop = vc.getScaledTouchSlop();
    switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_UP: {
            float currX = ev.getX();
            if (Math.abs(currX - originalX) > slop) {
                intercept = true;
            }
            break;
        }
        case MotionEvent.ACTION_DOWN: {
            originalX = ev.getX();
            break;
        }
    }

    return (super.onInterceptTouchEvent(ev) || intercept);
}

所以我的想法是只拦截向左/向右滑动,所有其他事件都应该留给子视图。滚动视图中的按钮似乎可以工作,但我的侦听器无论如何都不会被调用。

我在 xml 中的视图如下所示:

<com.damluar.mobile.inbox.MyScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="visible"
            android:id="@+id/detailLayout">
        <LinearLayout
                android:id="@+id/detailButtonLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="horizontal"
                android:background="@color/default_color">
        </LinearLayout>

    </LinearLayout>
</com.damluar.mobile.inbox.MyScrollView>

【问题讨论】:

    标签: android scrollview ontouchlistener


    【解决方案1】:

    如果有用,请检查并标记它。 我已经稍微更新了 OnSwipeTouchListener 以获得 onTouch 的回调。

    public class OnSwipeTouchListener implements OnTouchListener {
    private final GestureDetector gestureDetector = new GestureDetector(
            new GestureListener());
    
    @Override
    public boolean onTouch(final View view, final MotionEvent motionEvent) {
        return gestureDetector.onTouchEvent(motionEvent);
    
    }
    
    private final class GestureListener extends SimpleOnGestureListener {
    
        private static final int SWIPE_THRESHOLD = 50;
        private static final int SWIPE_VELOCITY_THRESHOLD = 50;
        private static final int SWIPE_DISTANCE = 50;
    
    
        private boolean isFlingCall = false;
    
        @Override
        public boolean onDown(MotionEvent e) {
            // TODO Auto-generated method stub
            isFlingCall = false;
            return true;
        }
    
    
    
        @Override
        public boolean onSingleTapUp(MotionEvent e){    
            if(!isFlingCall) {
                onTouch();
                return false;
            }
            else {
                return true;
            }
    
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD
                            && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > SWIPE_DISTANCE) {
                            isFlingCall = true;
                            onSwipeRight();
                            return true;
                        }
                        else {
                            onSwipeLeft();
                            return true;
                        }
                    }
                }
    
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            onTouch();
            return true;
        }
    }
    
    public void onSwipeRight() {
    }
    
    public void onSwipeLeft() {
    }
    public void onTouch() {
    }
    }
    

    谢谢

    JRH

    【讨论】:

    • 正如我所写的,我的触摸监听器永远不会被调用。所以你的听众在这种情况下并不好。
    猜你喜欢
    • 1970-01-01
    • 2020-01-29
    • 2020-12-21
    • 2013-02-17
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多