关于安卓recyclerview的子布局中,scrollview滑动冲突问题

简介: 安卓recyclerview的子布局中,scrollview滑动冲突问题

场景

recyclerivew使用PagerSnapHelper,子布局中,使用scrollview,观察,scrollview内容
区域超过高度时,滑动失效。

原因

recyclerview的触摸事件,没有分发到scrollview中,导致了scrollview的触摸事件失效。

解决方法

(1)当scrollview不需要滑动的时候,无需处理
(2)当scrollview需要滑动的时候,需要捕获触摸事件。对于捕获的事件后,需要判断
scrollview是否已经处于顶部/底部,若是,则不再处理触摸事件,否则需要处理触摸事件。

实现

(1)判断scrollview是否满足滑动的条件,原理是计算scrollview的子类总高度,再对比当前
scrollview的高度,判断是否满足,核心代码如下:

/**
 * 所有子布局高度
 */
private int getChildHeight() {
    if (getChildCount() == 0) {
        return 0;
    }
    int result = 0;
    for (int i = 0; i < getChildCount(); i++) {
        result = result + getChildAt(i).getMeasuredHeight();
    }
    return result;
}

/**
 * 是否有超出内容
 */
private boolean outSide() {
    return getChildHeight() > getMeasuredHeight();
}

(2)对scrollview进行滑动监听,初始化滑动到顶部/底部的变量,核心代码如下:

setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
    @Override
    public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
        try {
            if (scrollY > oldScrollY) {
                // 向下滑动
            }
            if (scrollY < oldScrollY) {
                // 向上滑动
            }
            if (scrollY == 0) {
                // 顶部
//                        LogUtil.d("PagerSnapScrollView onScrollChange top");
                mIsTop = true;
            } else {
//                        LogUtil.d("PagerSnapScrollView onScrollChange top2");
                mIsTop = false;
            }
            if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
                //底部
//                        LogUtil.d("PagerSnapScrollView onScrollChange bottom");
                mIsBottom = true;
            } else {
//                        LogUtil.d("PagerSnapScrollView onScrollChange bottom2");
                mIsBottom = false;
            }
        } catch (Exception e) {

        }
    }
});

(3)最后,在scrollview的事件分发中,进行分发的处理,核心代码如下:


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (outSide()) {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mDownY = (int) ev.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int endY = (int) ev.getY();
                    if ((mIsBottom && (mDownY > endY))) {
                        setDisallowIntercept(false);
                        return super.dispatchTouchEvent(ev);
                    }
                    if ((mIsTop && mDownY < endY)) {
                        setDisallowIntercept(false);
                        return super.dispatchTouchEvent(ev);
                    }
                    setDisallowIntercept(true);
                    return super.dispatchTouchEvent(ev);
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    return super.dispatchTouchEvent(ev);
            }
            setDisallowIntercept(false);
            return super.dispatchTouchEvent(ev);
        } else {
            return super.dispatchTouchEvent(ev);
        }
    }

that's all------------------------------------

代码地址,类名PagerSnapScrollView

目录
相关文章
|
2月前
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
|
4月前
|
移动开发 监控 前端开发
构建高效Android应用:从优化布局到提升性能
【7月更文挑战第60天】在移动开发领域,一个流畅且响应迅速的应用程序是用户留存的关键。针对Android平台,开发者面临的挑战包括多样化的设备兼容性和性能优化。本文将深入探讨如何通过改进布局设计、内存管理和多线程处理来构建高效的Android应用。我们将剖析布局优化的细节,并讨论最新的Android性能提升策略,以帮助开发者创建更快速、更流畅的用户体验。
74 10
|
3月前
|
Android开发 开发者 索引
Android实战经验之如何使用DiffUtil提升RecyclerView的刷新性能
本文介绍如何使用 `DiffUtil` 实现 `RecyclerView` 数据集的高效更新,避免不必要的全局刷新,尤其适用于处理大量数据场景。通过定义 `DiffUtil.Callback`、计算差异并应用到适配器,可以显著提升性能。同时,文章还列举了常见错误及原因,帮助开发者避免陷阱。
282 9
|
3月前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
81 8
|
2月前
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
174 0
|
4月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
74 1
|
5月前
|
Android开发 Kotlin
kotlin开发安卓app,如何让布局自适应系统传统导航和全面屏导航
使用`navigationBarsPadding()`修饰符实现界面自适应,自动处理底部导航栏的内边距,再加上`.padding(bottom = 10.dp)`设定内容与屏幕底部的距离,以完成全面的布局适配。示例代码采用Kotlin。
141 15
|
4月前
|
存储 Android开发 开发者
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
55 0
|
4月前
|
数据可视化 Java 数据挖掘
Android项目架构设计问题之设置RecyclerView的LayoutManager如何解决
Android项目架构设计问题之设置RecyclerView的LayoutManager如何解决
40 0
|
4月前
|
XML 数据可视化 API
Android经典实战之约束布局ConstraintLayout的实用技巧和经验
ConstraintLayout是Android中一款强大的布局管理器,它通过视图间的约束轻松创建复杂灵活的界面。相较于传统布局,它提供更高灵活性与性能。基本用法涉及XML定义约束,如视图与父布局对齐。此外,它支持百分比尺寸、偏移量控制等高级功能,并配有ConstraintSet和编辑器辅助设计。合理运用可显著提高布局效率及性能。
272 0