• 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),请求父组件恢复拦截

    核心代码

    1. //最大递归深度,避免异常,防止嵌套层级导致判断无效
    2. int MAX_PARENT_DEPTH = 3;
    3. @Override
    4. public boolean onTouchEvent(MotionEvent event) {
    5. if (event.getAction() == MotionEvent.ACTION_DOWN) {
    6. ViewParent viewParent = findViewParentIfNeeds(this, MAX_PARENT_DEPTH);
    7. if(viewParent != null){
    8. // 父组件不要拦截
    9. viewParent.requestDisallowInterceptTouchEvent(true);
    10. }
    11. }
    12. return super.onTouchEvent(event);
    13. }
    14. private ViewParent findViewParentIfNeeds(View tag, int depth){
    15. if (depth < 0) {
    16. return null;
    17. }
    18. ViewParent parent = tag.getParent();
    19. if (parent == null) {
    20. return null;
    21. }
    22. if (parent instanceof ScrollView || parent instanceof ViewPager){
    23. return parent;
    24. }
    25. return findViewParentIfNeeds((View) parent, depth - 1);
    26. }
    1. @Override
    2. protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY){
    3. if (clampedX || clampedY) {
    4. ViewParent viewParent = findViewParentIfNeeds(this, MAX_PARENT_DEPTH);
    5. if (viewParent != null) {
    6. // 父组件可以根据自身判断来决定是否拦截
    7. viewParent.requestDisallowInterceptTouchEvent(false);
    8. }
    9. }
    10. super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    11. }

    参考文档

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

  • 相关阅读:
    MTK2735(1)——环境相关linux(ADB调试)
    进程线程知识之线程同步
    Springboot 集成 Ehcache操作数据库显示SQL语句设置
    Maven私服仓库配置-Nexus详解
    机器学习绪论
    Ubuntu 传输文件
    麒麟v10系统,在虚拟机上直接连公司同一个局域网,设置静态ip
    mysql 普通索引 limit 慢的问题
    MySQL-Day02 数据库以及数据表的基本操作
    数学之-曼德勃罗
  • 原文地址:https://blog.csdn.net/yaojie5519/article/details/126677539