问题记录-CoordinatorLayout+WebView使用遇到的问题
需求背景:
使用CoordinatorLayout+viewpager+tablayout+webview实现首页折叠效果。
使用问题:
在使用过程中首页的页面为原生/h5混合页,在原生页面正常,嵌套h5页面头部CollapsingToolbarLayout无法滚动,开始的解决方式是在webview上面嵌套NestedScrollView。
项目上线后发现了新的问题,h5关于滑动的js都无法执行。
原因分析:
引用Coordinator layout 和 WebView中的话是:
如果将webview放在NestedScrollView中,height是wrap_contents,并且webview扩展为页面的大小。 因此无法垂直滚动。 滚动是在NestedScrollView而不是webview本身发生的。
所以页面中没有js的结果会看到任何滚动事件,所以它不知道你已经滚动到页面的末尾加载更多的内容。
硬件层也由GL纹理支持,并且它们具有最大尺寸(这是最小的屏幕尺寸,尽管通常不会大得多)。 如果视图变得大于最大纹理大小,那么它将不能与硬件层一起使用。 这适用于任何视图,而不仅仅是webview。
建议:
不要将webview放在NestedScrollView中。 不要在wrap_contents模式下使用webview。 让webview滚动网页本身。
解决方案:
自定义webview,由它实现NestedScrollingChild。
package com.ingtube.common.widget; import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent; import androidx.core.view.MotionEventCompat;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat; public class NestedScrollWebView extends ScrollWebView implements NestedScrollingChild {
public NestedScrollWebView(@NotNull Context context) {
super(context);
init();
} public NestedScrollWebView(@NotNull Context context, @NotNull AttributeSet attrs) {
super(context, attrs);
init();
} public NestedScrollWebView(@NotNull Context context, @NotNull AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private int mLastMotionY; private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2]; private int mNestedYOffset; private NestedScrollingChildHelper mChildHelper; private void init() {
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = false; MotionEvent trackedEvent = MotionEvent.obtain(event); final int action = MotionEventCompat.getActionMasked(event); if (action == MotionEvent.ACTION_DOWN) {
mNestedYOffset = 0;
} int y = (int) event.getY(); event.offsetLocation(0, mNestedYOffset); switch (action) {
case MotionEvent.ACTION_DOWN:
mLastMotionY = y;
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
result = super.onTouchEvent(event);
break;
case MotionEvent.ACTION_MOVE:
int deltaY = mLastMotionY - y; if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
trackedEvent.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
} int oldY = getScrollY();
mLastMotionY = y - mScrollOffset[1];
int newScrollY = Math.max(0, oldY + deltaY);
deltaY -= newScrollY - oldY;
if (dispatchNestedScroll(0, newScrollY - deltaY, 0, deltaY, mScrollOffset)) {
mLastMotionY -= mScrollOffset[1];
trackedEvent.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
if(mScrollConsumed[1]==0 && mScrollOffset[1]==0) {
trackedEvent.recycle();
result = super.onTouchEvent(trackedEvent);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
stopNestedScroll();
result = super.onTouchEvent(event);
break;
}
return result;
} // NestedScrollingChild @Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
} @Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
} @Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
} @Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
} @Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
} @Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
} @Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
} @Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
} @Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
} }
参考链接:
解决coordinatorlayout嵌套webView遇到的问题
问题记录-CoordinatorLayout+WebView使用遇到的问题的更多相关文章
- WebView使用详解(二)——WebViewClient与常用事件监听
登录|注册 关闭 启舰 当乌龟有了梦想…… 目录视图 摘要视图 订阅 异步赠书:Kotlin领衔10本好书 免费直播:AI时代,机器学习如何入门? 程序员8 ...
- 《Android编程权威指南》PhotoGallery应用梳理
PhotoGalley是<Android编程权威指南>书中另外一个重要的应用.
- Android WebView默认GONE出现的问题记录
前段时间重构一批相似度80%以上的项目[真搞不懂前人们是怎么忍受十几个类似的应用一直CVU的,冗余代码和资源达到40%以上] 其中需要抽出一个公共的带WebView的Activity基类,由于脑残测试 ...
- appium+python自动化42-微信公众号 (可能以后会遇到也遇到切换不了webview的问题 记录再此 还没试)
前言 本篇介绍如何在微信公众号上自动化测试,以操作我的个人公众号:yoyoketang为例,没关注的,先微信关注了,再跟着操作 环境准备:python 3.6appium 1.7以上版本微信6.6.6 ...
- 切换了webview 定位不了的解决方法 (还没有试,记录在此)
# 切换到 webview time.sleep(2) print(driver.contexts) driver.switch_to.context('WEBVIEW_com.tencent.mm: ...
- 小程序web-view wx.miniProgram.postMessage 坑记录
web-view吧,其实微信官方应该是非常不支持在小程序上嵌套web的,它希望你直接用小程序上的代码,而放弃web的实现,当然,也是为了防止用小程序去嵌套别的广告页面.所以官方对web-view的操作 ...
- Appium Hybrid混合应用测试——Native切换WebView , 切换不了WebView (没有试过,先记录在此)
Appium Hybrid混合应用测试过程中,经常需要在Native和WebView之间进行切换: 1.切换至WEBVIEW操作: for cons in driver.contexts: if co ...
- Android。WebView加载UR请求使用Cookie储存User_Id记录用户是否登陆过
1.WebView初始化的时候用倒如下代码: if (Build.VERSION.SDK_INT >= 21) { CookieManager.getInstance().setAcceptTh ...
- Android webview 问题记录
1. Android 7.1真机安装调试apk时报错,解析安装包失败 原因:sdk版本不支持7.1版本,需要调整minSdkVersion等参数,支持低版本 解决方法: android { compi ...
随机推荐
- MeteoInfoLab脚本示例:subplot
subplot命令可以自动等间距分配多个坐标系(Axes),命令中有三个参数,前两个定义了行数和列数,第三个指定了当前的坐标系(Axes),绘图命令是作用在当前坐标系中的. 脚本程序: def f(t ...
- day19 Pyhton学习 递归函数
# 函数的递归 : 在一个函数的内部调用它自己 # import sys # sys.setrecursionlimit(1000000) # 设置递归的最大深度 # 总结 # 1.递归函数的定义 : ...
- spring boot:thymeleaf给fragment传递参数的方法(spring boot 2.3.3)
一,thymeleaf如何给fragment传递参数? 1,如果是全局的参数,可以用interceptor中传递 非全局参数,可以从controller中传递 2,引用片断时也可以传递参数 说明:刘宏 ...
- IDEA 半天卡住buid(编译)不动
[号外号外!] 最终解决办法并不复杂,关键在于"遇见问题,怎么样层层分析,多条路径试错,最终解决问题的思路或者能力"--资深码农的核心竞争力之一 背景 今天结束完最近2个月的一个项 ...
- axb_2019_heap-format_string + off-by-one
axb_2019_heap 简单题,格式化字符串泄漏栈地址 算上rsp,格式化字符串参数是栈顺序+6-1 edit有off by one 构造unlink chunk0 chunk1 chunk2 构 ...
- FFmpeg 将大量图片合成为视频 video
1.基本格式终端输入: ffmpeg -f image2 -i /home/ttwang/images/image%d.jpg tt.mp4其中/home/ttwang/images/images%d ...
- Go module 本地导包方式
tip本文只讲关于Go module 本地导包方式,其他请自行查阅 Go module 导包方式,go mod init project-name,会得到一个go.mod文件,此文件是管理依赖的,通常 ...
- 回顾C#各版本特性
C# 6.0 Read-only auto-properties(只读自动属性) 以前版本,声明只读属性时,示例: public string FirstName { get; private set ...
- 【转】Getting an Image on the Screen
FROM:http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php Getting an Image o ...
- 测试TwemProxy的应知应会
一.背景 最近中间件开发组对twemproxy的发现注册机制做了改造,之前没有接触过twemproxy,借这次测试的机会,初步学习了一下twemproxy相关的知识:下面用"测试语言&quo ...