SwipeRefreshLayout中的Horizo​​ntalScrollView

 书友76075933 发布于 2023-01-12 10:56

我实现了新的SwipeRefreshLayout成分在我的应用程序,它与任何垂直意见工作得很好,比如ListView,GridViewScrollView.

它在水平视图中表现得很糟糕,比如HorizontalScrollView.向右或向左滚动时,SwipeRefreshLayout视图会缓存触摸,阻止HorizontalScrollView接收并开始垂直滚动以执行刷新.

我尝试解决这个问题,因为我之前解决了ScrollViewViewPager内部垂直问题,使用requestDisallowInterceptTouchEvent但它没有用.我还注意到,在原始SwipeRefreshLayout类中重写此方法而不返回super.谷歌的开发者留下了评论" //Nope.":)

因为SwipeRefreshLayout组件相对较新,我找不到修复水平滚动问题的解决方案,同时仍然允许滑动刷新视图以跟踪和处理垂直滚动,所以我想我会分享我的解决方案,希望它会让人节省一个小时或两个.

2 个回答
  • 如果您没有记住已经拒绝了ACTION_MOVE事件的事实,那么如果用户返回到您的初始mPrevX附近,您最终会在以后使用它.

    只需添加一个布尔值来记住它.

    public class CustomSwipeToRefresh extends SwipeRefreshLayout {
    
        private int mTouchSlop;
        private float mPrevX;
        // Indicate if we've already declined the move event
        private boolean mDeclined;
    
        public CustomSwipeToRefresh(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mPrevX = MotionEvent.obtain(event).getX();
                    mDeclined = false; // New action
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    final float eventX = event.getX();
                    float xDiff = Math.abs(eventX - mPrevX);
    
                    if (mDeclined || xDiff > mTouchSlop) {
                        mDeclined = true; // Memorize
                        return false;
                    }
            }
    
            return super.onInterceptTouchEvent(event);
        }
    }
    

    2023-01-12 10:58 回答
  • 我通过扩展SwipeRefreshLayout和覆盖它来解决它onInterceptTouchEvent.在里面,我计算用户徘徊的X距离是否大于触摸坡度.如果是,则表示用户正在水平滑动,因此我返回false,让孩子查看(HorizontalScrollView在这种情况下)获取触摸事件.

    public class CustomSwipeToRefresh extends SwipeRefreshLayout {
    
        private int mTouchSlop;
        private float mPrevX;
    
        public CustomSwipeToRefresh(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mPrevX = MotionEvent.obtain(event).getX();
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    final float eventX = event.getX();
                    float xDiff = Math.abs(eventX - mPrevX);
    
                    if (xDiff > mTouchSlop) {
                        return false;
                    }
            }
    
            return super.onInterceptTouchEvent(event);
        }
    }
    

    2023-01-12 10:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有