每当我更改 css 类时,更改并不总是出现。当我有一个触摸事件向按钮添加类似向下类名称的内容时,这似乎会发生。该按钮不会更新,页面上的任何其他内容也不会更新。它的工作时间非常不稳定。我还注意到有时我的元素显示为白色,没有任何内容或任何内容。这非常令人沮丧!
原文由 Kyle 发布,翻译遵循 CC BY-SA 4.0 许可协议
笔记:
从 Android 4.4+ 开始有更好的解决方案。这是一个名为 CrossWalk 的替代品 WebView
替代品。它使用最新的 Chromium-kit,非常棒。你可以在这里阅读它: crosswalk-project.org
此外,似乎自 Android 4.4 以来,不再需要 invalidate()
解决方案,您可以使用其他一些更安全的答案。我只会使用这种 invalidate()
方法作为最后的努力。
我正在回答我自己的问题,希望能帮助那些和我有同样问题的人。
我已经尝试了几种方法来让事情变得更好,甚至是所有臭名昭著的 - webkit-transform: translate3d(0,0,0);
即使那样也不太奏效。
让我与您分享有效的方法。
首先,使用最新的 API。我正在使用 API 15。在你的 AndroidManifest.xml
中,确保启用 _硬件加速_。如果您的 API 版本不支持此功能,请继续下一步。
如果您的版本确实支持它,您可以通过修改清单来启用它:
<application
...
android:hardwareAccelerated="true">
此外,请确保您的清单具有对您正在使用的 API 的最低支持 API。因为我使用的是 API 15,所以这是我的清单:
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
( 更新:您现在应该修改您的值 build.gradle
)
现在,在您的主要 CSS 文件中,对于将在 WebView 中显示的内容,添加如下内容:
body div {
-webkit-transform: translate3d(0,0,0);
}
使用您拥有的任何其他元素类型添加到 body div 位;您可能可以排除图像, ul
, li
等。将此 CSS 样式应用于所有内容的原因只是通过反复试验,我发现将其应用于所有内容似乎效果最好。对于更大的 DOM 树,您可能需要更加具体。但是,我不确定规格是什么。
当您实例化您的 WebView
时,您需要设置一些设置:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
appView.getSettings().setRenderPriority(RenderPriority.HIGH);
appView.getSettings()
.setPluginState(WebSettings.PluginState.ON_DEMAND);
}
倒数第二个但至关重要的一点:我正在阅读 WebView
类的源代码,发现这个关于强制重绘的小注释。有一个 static final boolean
,当设置为 true
将强制视图始终重绘。我对 Java 语法不是很了解,但我认为您不能直接更改类的静态最终属性。所以我最终做的是像这样扩展课程:
import org.apache.cordova.CordovaWebView;
import android.content.Context;
import android.graphics.Canvas;
public class MyWebView extends CordovaWebView {
public static final String TAG = "MyWebView";
public MyWebView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Warning! This will cause the WebView to continuously be redrawn
// and will drain the devices battery while the view is displayed!
invalidate();
}
}
请记住,我使用的是 Cordova/PhoneGap,因此我必须从 CordovaWebView
进行扩展。如果您在 onDraw 方法中看到,有一个对 invalidate
的调用。这将导致视图不断重绘。但是,我强烈建议添加逻辑以仅在需要时重绘。
如果您使用的是 Cordova,则还有最后一步。您必须告诉 PhoneGap 使用您的新 WebView
类而不是他们自己的 WebView
类。在您的 MainActivity
类中,添加以下内容:
public void init(){
CordovaWebView webView = new MyWebView(MainActivity.this);
super.init(webView, new CordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView));
}
而已!尝试运行您的应用程序,看看一切是否更流畅。在进行所有这些更改之前,页面会显示为白色,直到再次点击屏幕后才会应用任何 CSS 更改,动画非常不稳定甚至不明显。我应该提到动画仍然不稳定,但远没有以前那样不稳定。
如果有人对此有任何补充,请在下面发表评论。我总是对优化持开放态度;而且我完全知道可能有更好的方法来完成我刚刚推荐的事情。
如果我的上述解决方案对您不起作用,您能否描述您的具体情况以及您在 Androids WebView
上看到的结果?
最后,我已将此答案启用为 “社区维基” ,因此任何人和每个人都可以随意进行调整。
谢谢!
编辑:
使用最新的 PhoneGap,您需要让您的 init() 方法看起来更像这样:
public void init(){
CordovaWebView webView = new MyWebView(MainActivity.this);
super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView));
}
原文由 Kyle 发布,翻译遵循 CC BY-SA 3.0 许可协议
2 回答858 阅读✓ 已解决
4 回答950 阅读✓ 已解决
2 回答1.4k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
2 回答829 阅读✓ 已解决
2 回答1k 阅读✓ 已解决
2 回答2.6k 阅读
我实施了 kyle 的解决方案并解决了问题。然而,当应用程序打开时,我注意到 android 4.0.4 上的电池消耗量很大。同样在更改之后,我有用户抱怨 swiftKey 键盘不再适用于我的应用程序。
我的应用程序中的每个更改都是由用户操作触发的,因此我想出了一个修改版本,它只在 touchEvent 之后触发 invalidate():
从来没有用 Java 进行过任何编程,所以可能有更好的解决方案来做到这一点。