当前位置: 首页 > news >正文

Webview+Viewpager左右滑动冲突

问题描述

在开发场景中,经常需要Viewpager+Fragment嵌套滑动页面。然而若某个Fragment为webview,且webview中存在轮播图或者其他滑动控件,则会出现Webview内容无法左右滑动的问题。

原因分析

其实滑动冲突问题的本质,是滑动事件的分发和消费不对。

一般,我们需要明确,这个事件应该由谁来消费,实际上是谁消费了,分发过程是否正确,是否需要拦截等,想清楚这些问题基本就找到解决思路了。

若对Android事件机制不够熟悉,可以先温习一遍事件机制原理再往下看。

在上述的问题场景中,我们可以确定正确思路:这个事件应该由webivew先响应,如果webview不需要内部滑动了(左右滑到边了),再交给Viewpage处理事件。

解决方案

1.WebView onTouchEvent方法

查找父组件是否为可以滑动的视图(如ViewPager),是则调用requestDisallowInterceptTouchEvent(true),请求父组件不要拦截

2.WebView onOverScrolled

当clampedX或者clampedY值为true,此时不再响应内部滑动。调用requestDisallowInterceptTouchEvent(false),请求父组件恢复拦截

核心代码

//最大递归深度,避免异常,防止嵌套层级导致判断无效
int MAX_PARENT_DEPTH = 3;

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        ViewParent viewParent = findViewParentIfNeeds(this, MAX_PARENT_DEPTH);
        if(viewParent != null){
            // 父组件不要拦截
            viewParent.requestDisallowInterceptTouchEvent(true);
        }
    }
    return super.onTouchEvent(event);
}

private ViewParent findViewParentIfNeeds(View tag, int depth){

    if (depth < 0) {
        return null;
    }

    ViewParent parent = tag.getParent();
    if (parent == null) {
        return null;
    }

    if (parent instanceof ScrollView || parent instanceof ViewPager){
        return parent;
    }
    return findViewParentIfNeeds((View) parent, depth - 1);
}
@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY){
    if (clampedX || clampedY) {
        ViewParent viewParent = findViewParentIfNeeds(this, MAX_PARENT_DEPTH);
        if (viewParent != null) {
            // 父组件可以根据自身判断来决定是否拦截
            viewParent.requestDisallowInterceptTouchEvent(false);
        }
    }

    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}

参考文档

处理 WebView 与 ViewPager 滑动冲突 - 技术小黑屋

相关文章:

  • 【 C++ 】多态
  • jupyter 基本用法
  • Unity入门01——unity界面基础
  • 【05】Yarn
  • Flutter 从源码看Getx的依赖原理
  • JavaScript 知识梳理基础篇(二)
  • 【web-代码审计】(14.4)ASP.NET
  • 一、Maven-单一架构案例(创建工程,引入依赖,搭建环境:持久化层,)
  • vue-cli 初始----安装运行Vue项目
  • 华尔街日报请求分析
  • Ubuntu18.04安装深度学习环境(Anaconda、显卡驱动、CUDA、Tensorflow-GPU等)
  • Linux关于yum和vim入门的一些问题
  • 网络请求(四)—Socket
  • Python中的模块
  • JavaEE、Spring
  • AngularJS指令开发(1)——参数详解
  • CSS 三角实现
  • Docker下部署自己的LNMP工作环境
  • Hibernate最全面试题
  • Linux gpio口使用方法
  • Linux各目录及每个目录的详细介绍
  • ubuntu 下nginx安装 并支持https协议
  • vue-cli3搭建项目
  • Wamp集成环境 添加PHP的新版本
  • Yii源码解读-服务定位器(Service Locator)
  • 彻底搞懂浏览器Event-loop
  • 基于Android乐音识别(2)
  • 检测对象或数组
  • 思维导图—你不知道的JavaScript中卷
  • 学习笔记TF060:图像语音结合,看图说话
  • 在weex里面使用chart图表
  • 自制字幕遮挡器
  • ![CDATA[ ]] 是什么东东
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #在 README.md 中生成项目目录结构
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转) 深度模型优化性能 调参
  • (转)scrum常见工具列表
  • (转)可以带来幸福的一本书
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET/C# 的字符串暂存池
  • .NetCore部署微服务(二)
  • /bin、/sbin、/usr/bin、/usr/sbin
  • @Autowired 与@Resource的区别
  • @Data注解的作用
  • @RequestBody的使用
  • @RestControllerAdvice异常统一处理类失效原因
  • @Transactional 详解
  • [100天算法】-二叉树剪枝(day 48)
  • [CDOJ 1343] 卿学姐失恋了