Android Webview滑进出屏幕闪烁的解决方法
作者:ganshenml 发布时间:2021-11-30 11:57:33
前言
在使用Webview进行滑动操作时,从屏幕可见区域外向内滑动时,会出现webview区域闪烁的问题(反之也是),本文将提供一种解决方案。
问题图示
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="@color/colorPrimary" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/contract_font"></WebView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
可以看到,NestedScrollView嵌套webview,且webview初始未在一屏内时,滑进出屏幕时会有短暂的白色块。
解决问题
方案对比
方案 | 考虑点 |
---|---|
android:hardwareAccelerated="false" | 5.0 开始Android系统为了充分利用GPU的特性,使得界面渲染更加平滑而默认开启的,如果关掉的话,那么整个网页不流畅了,岂不是得不偿失——>放弃 |
setBackgroundColor(Color.parseColor(“#00000000”)); setBackgroundResource(R.drawable.white); | 设置底色背景,但是webview本身是加载的H5页面,使用的是H5页面的底色背景,而且通过上面的gif可以看出,没有效果——>放弃 |
==通过样式布局,让webview保持在第一屏内初始化== | 本文尝试的方案 |
方案探索
1.xml布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/contract_font"></WebView>
<View
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="@color/colorPrimary" />
</FrameLayout>
</android.support.v4.widget.NestedScrollView>
通过FrameLayout来叠加使得webview保持在第一屏内初始化,然后设置webview的padding,这样使得完整的H5内容是在ContentView下方显示。
但是——>webview设置padding根本无效!!!
怎么办呢?无论怎样也想不到为什么会如此,毕竟本身api的实现上是有些缺陷的(https://stackoverflow.com/questions/9170042/how-to-add-padding-around-a-webview )
2.解决问题
最终的解决方案则是通过注入js代码来控制H5的padding来解决。
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
contentView.post(new Runnable() {
@Override
public void run() {
contentViewHeight = px2dp(getApplicationContext(), contentView.getMeasuredHeight());
if (contentViewHeight > 0) {
webView.loadUrl("javascript:document.body.style.marginTop=\"" + contentViewHeight + "px\"; void 0");
}
}
});
}
});
看下猜想运行的结果:
H5的显示缺少了顶部,这样看来padding是没有效果的。但是,为什么会没有效果呢,难道设置padding有问题?
之后查看了上面嵌入的网页的源码查看了下(网页是网络上随便找的一个url):
https://36kr.com/
打开网页编辑模式,查看body这块的样式:
可以看到要注入的js控制的样式这块是没有设置的。因此可以将padding-top的参数通过这里设置进去。
但是发现设置的该参数无效,是什么原因呢?接着往下翻:
原来是body中控制了padding-top的最高级样式显示,所以element-style中设置无效。所以要么把这段注释掉,重新写入至element-style中,要么尝试设置margin-top的方法。这里采用后者的做法:
可以看到,网页顶部出现了设置好的marin-top空白的高度。
只需要将这部分操作转换为对应的代码即可:
将上面的
webView.loadUrl("javascript:document.body.style.paddingTop="" + contentViewHeight + "px"; void 0");
替换为:
webView.loadUrl("javascript:document.body.style.marginTop=\"" + contentViewHeight + "px\"; void 0");
3.运行效果
可以看到已经没有闪烁了。
总结
整个方案的实现其实就两块:
1.布局,让webview在一屏内初始;
2.设置H5网页的margin-top或者padding-top;
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。
来源:https://juejin.im/post/5c85debdf265da2de450adf8


猜你喜欢
- JDK集合源码之HashMap解析1.树结构入门1.1 什么是树?树(tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据
- 引言在实际分布式项目中延迟任务一般不会使用JDK自带的延迟队列,因为它是基于JVM内存存储,没有持久化操作,所以当服务重启后就会丢失任务。在
- 首先备注一下JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。为 J2EE
- 前言在前一节的学习中,慕歌带大家使用了全局结果集返回,通过使用全局结果集配置,优雅的返回后端数据,为前端的数据拿取提供了非常好的参考。同时通
- 引言:在Object基类中,有一个方法叫clone,产生一个前期对象的克隆,克隆对象是原对象的拷贝,由于引用类型的存在,有深克隆和浅克隆之分
- 同步客户端套接字示例 下面的示例程序创建一个连接到服务器的客户端。该客户端是用同步套接字生成的,因此挂起客户端应用程
- Synchronized实现可见性原理可见性要实现共享变量的可见性,必须保证两点:线程修改后的共享变量值能够及时从工作内存刷新到主内存中其他
- 因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能。我根据网上网友提供的一些资料,自己整合应用到项目中,效
- Spring在Java EE开发中是实际意义上的标准,但我们在开发Spring的时候可能会遇到以下令人头疼的问题:(1)大量配置文件的定义;
- 折半搜索,也称二分查找算法、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。A 搜素过程从数组的中间元素开始,如果中间元素正好是要查
- 1. 前言Compose 具有超强的兼容性,兼容现有的所有代码,Compose 能够与现有 View 体系并存,可实现渐进式替换。这就很有意
- 最近在公司的功能需求中,需要实现可以签到的日历,签到后在签到过的日期做标志。本功能参考了网上一些大神的日历控件,在此基础上进行修改,已满足本
- Unity是不识别Gif格式图的,需要我们使用c#将gif里多帧图转化为Texture2D格式。需要使用System.Drawing.dll
- Android 自定义dialog的实现代码搜索相关关键字网上一大堆实现,但是看完总觉得缺胳膊少腿,绕了不少弯路,终于弄好了自定义dialo
- Android 中的危险权限详细整理前言:Android 中有上百种权限,现在将所有的权限归为两类:一类是普通权限一类的危险权限普通权限是指
- 前言Android 8.0系统更新之后,app的更新将不再像之前的系统版本一样能够直接下载安装包之后直接安装(以前安装未知来源应用的时候一般
- SpringTask是Spring自带的功能。实现起来比较简单。使用SpringTask实现定时任务有两种方式:1.注解方式基于注解@Sch
- 在C#中用同一个dataset保存从数据库中取出的多张表:cmd.CommandText = "select * from tab
- 本文将介绍在REST API中实现分页的基础知识。我们将专注于使用Spring Boot和Spring Data 在Spring MVC中构
- 本文实例为大家分享了Java实现斗地主的具体代码,供大家参考,具体内容如下import java.util.ArrayList;import