为了账号安全,请及时绑定邮箱和手机立即绑定

滚动视图触摸处理中的HorizontalScrollView

滚动视图触摸处理中的HorizontalScrollView

森林海 2019-06-25 11:27:18
滚动视图触摸处理中的HorizontalScrollView我有一个滚动视图围绕我的整个布局,使整个屏幕是可滚动的。我在这个ScrollView中拥有的第一个元素是HorizontalScrollView块,它具有可以水平滚动的功能。我在水平滚动视图中添加了一个ontouch侦听器,以处理触摸事件,并强制视图“快照”到action_up事件上最接近的图像。所以我想要的效果就像股票Android的主屏幕,你可以从一个屏幕滚动到另一个屏幕,当你举起手指的时候它会点击到一个屏幕上。这一切都很好,除了一个问题:我需要从左到右滑动几乎完全水平,一个action_up永远注册。如果我最不垂直地滑动(我认为很多人倾向于在手机上来回滑动),我将收到action_Cancel而不是action_up。我的理论是,这是因为水平滚动视图在滚动视图中,而滚动视图正在劫持垂直触摸以允许垂直滚动。如何从水平滚动视图中禁用滚动视图的触摸事件,但仍然允许在滚动视图的其他地方正常垂直滚动?下面是我的代码示例:public class HomeFeatureLayout extends HorizontalScrollView {private ArrayList<ListItem> items = null; private GestureDetector gestureDetector;View.OnTouchListener gestureListener;private static final int SWIPE_MIN_DISTANCE = 5; private static final int SWIPE_THRESHOLD_VELOCITY = 300;private int activeFeature = 0; public HomeFeatureLayout(Context context, ArrayList<ListItem> items){     super(context);     setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));     setFadingEdgeLength(0);     this.setHorizontalScrollBarEnabled(false);     this.setVerticalScrollBarEnabled(false);     LinearLayout internalWrapper = new LinearLayout(context);     internalWrapper.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));     internalWrapper.setOrientation(LinearLayout.HORIZONTAL);     addView(internalWrapper);     this.items = items;     for(int i = 0; i< items.size();i++){         LinearLayout featureLayout = (LinearLayout) View.inflate(this.getContext(),R.layout.homefeature,null);         TextView header = (TextView) featureLayout.findViewById(R.id.featureheader);         ImageView image = (ImageView) featureLayout.findViewById(R.id.featureimage);         TextView title = (TextView) featureLayout.findViewById(R.id.featuretitle);
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

我想明白了。在我的ScrollView上,我需要覆盖onInterceptTouchEvent方法,以便只在Y运动大于X运动时拦截触摸事件。ScrollView的默认行为似乎是在有Y运动时拦截触摸事件。因此,通过修复,ScrollView只会在用户有意向Y方向滚动,并且在这种情况下将action_Cancel传递给子用户时,才会拦截该事件。

下面是包含HorizontalScrollView的滚动视图类的代码:

public class CustomScrollView extends ScrollView {
    private GestureDetector mGestureDetector;

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new YScrollDetector());
        setFadingEdgeLength(0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
    }

    // Return false if we're scrolling in the x direction  
    class YScrollDetector extends SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {             
            return Math.abs(distanceY) > Math.abs(distanceX);
        }
    }}


查看完整回答
反对 回复 2019-06-25
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

我简化了代码(不需要GestureDetector)达到同样的效果:

public class VerticalScrollView extends ScrollView {
    private float xDistance, yDistance, lastX, lastY;

    public VerticalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @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 super.onInterceptTouchEvent(ev);
    }}


查看完整回答
反对 回复 2019-06-25
  • 3 回答
  • 0 关注
  • 563 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号