【问题标题】:Dialog animation messed up by webview: android bug?对话框动画被 webview 搞砸了:android bug?
【发布时间】:2013-07-30 01:08:09
【问题描述】:

我用 Enter 和 Exit 慢速动画制作了一个对话框。但是该对话框包含一个 webview myMsg(加载本地文件,因此没有延迟)并弄乱了动画。

使用下面的代码(无 web 视图),对话框可以完美运行,在 Enter 和 Exit 处都具有动画效果。但是,如果我取消注释 行//builder.setView(myMsg),Exit 动画仍然可以完美运行,但是 Enter 动画没有执行(或执行得太快)。有趣的是,如果我将应用程序最小化并再次将其最大化,则 Enter 对话框动画执行得很好。

这就像 webview 加载弄乱了 Enter 动画。我尝试在加载 webview 后显示对话框,结果相同。

这不是疯了吗?关于发生了什么以及如何解决它的任何线索?任何帮助将不胜感激。

这是代码的相关部分:

    WebView myMsg = new WebView(context);
    myMsg.loadUrl("file:///android_asset/page.html");

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setIcon(R.drawable.ic_launcher);
    //builder.setView(myMsg);
    builder.setTitle("Some Title");
    final AlertDialog dialog = builder.create();

    WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
    lp.windowAnimations = R.style.AnimateDialog;

    dialog.show();
    dialog.getWindow().setAttributes(lp);

在样式方面,

<style name="AnimateDialog">
    <item name="android:windowEnterAnimation">@anim/in_left</item>
    <item name="android:windowExitAnimation">@anim/out_left</item>
</style>

编辑

我尝试使用setWebViewClient,但没有运气(没有dialog.getWindow().setLayout... 行,Enter 动画根本不起作用):

    WebView myMsg = new WebView(context);
    myMsg.getSettings().setJavaScriptEnabled(true);
    myMsg.loadUrl("file:///android_asset/" + page);
    myMsg.setBackgroundColor(0);
    myMsg.setSoundEffectsEnabled(true);

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setIcon(R.drawable.ic_launcher);
    builder.setTitle("SomeTitle");
    builder.setView(myMsg);
    final AlertDialog dialog = builder.create();

    myMsg.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            dialog.show();
            dialog.getWindow().setWindowAnimations(R.style.AnimateDialog);
            dialog.getWindow().setLayout(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.FILL_PARENT);
        }
    }

EDIT2

我还尝试使用 Dialog 而不是 AlertDialog,使用 xml 布局,遇到相同的问题(也尝试使用 WebView.loadData 而不是 WebView.loadUrl,同样的问题):

    final Dialog d = new Dialog(context);
    d.setContentView(R.layout.viewhtml);
    d.setTitle("SomeTitle");
    // Without this, Enter animation does not work
    d.getWindow().setLayout(WindowManager.LayoutParams.FILL_PARENT,
            WindowManager.LayoutParams.FILL_PARENT);
    WebView wv = (WebView) d.findViewById(R.id.webview);
    wv.loadUrl("file:///android_asset/" + page);
    wv.setBackgroundColor(0);
    d.getWindow().setWindowAnimations(R.style.AnimateDialog);
    wv.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            d.show();
        }
    });

这是 Dialog xml 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<WebView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:soundEffectsEnabled="true" >
</WebView>

</LinearLayout>

EDIT3

我刚刚意识到将TextViewTextView.setText(Html.fromHTML...) 一起使用而不是WebView 时会发生同样的问题。此外,如果我在dialog.show() 之后添加dialog.getWindow().setLayout(600,800) ,则动画按预期执行。所以看来问题是在事先不知道对话框大小的情况下不执行动画?

【问题讨论】:

    标签: android android-webview android-animation android-alertdialog


    【解决方案1】:

    我有一个类似的问题,但我不想放动画,而是想禁用它,因为它弄乱了我的 Dialog with WebView 的明显加载时间。我实际上能够禁用主窗口动画进入/退出,因为它不再淡入/淡出,但问题是 WebView 的内容大部分时间都被对话框的幻灯片动画延迟,我也在尝试禁用(我真的认为如果禁用窗口动画,则应该禁用所有动画)。

    根据我的测试,这实际上是一个 Jellybean 错误,但它在 Android 4.3 中最为明显,额外的动画搞砸了我的弹出窗口。不过 ICS 没有问题。

    如果您尝试通过 Android 设置 -> 开发人员选项 -> 窗口动画比例来增加默认动画时间,例如 5 甚至 10,您会注意到内容现在显示更加延迟。但是如果关闭动画,显示会很快。我相信如果默认动画被禁用,您的动画也可能会起作用。

    我认为这种行为是果冻豆错误,仅当您在 Dialog 中使用 WebView 时才会出现。该对话框在动画时间之后放置 WebView 内容,即使它应该已经被禁用,因为它随着高度的增长而滑动。

    我尝试的另一个解决方案是缓存 Dialog 以便可以重复使用。我的问题消失了,但有时无法正确调整大小以适应实际的 HTML 内容。现在,如果您的内容在显示时的长度基本相同,您可能只需要缓存您的 Dialog。

    希望我给了你很多线索。

    【讨论】:

    • 我在ICS和JB有同样的问题,所以不是JB问题。关于您的回答还有两个问题:如何禁用默认动画?如何缓存我的网页视图?我有一些奇怪的行为是,如果我设置dialog.getWindow().setLayout(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.FILL_PARENT),那么动画就可以执行。但WRAP_CONTENT 不是。非常感谢您花时间写下您的详细答案。
    • 我遇到的另一个问题,即使使用WindowManager.LayoutParams.FILL_PARENT,也是在动画结束后(0.15s)加载 webview 内容,除非我要求很长的动画时间(0.5s)。
    • 我已经在真实设备上进行了额外的测试,发现我讨论过的行为只存在于 Android 4.3 中(我之前对旧版本 Jelly bean 的测试只使用了非常慢的模拟器) .如果您对动画的行为也出现在 ICS 和 JB 中,则可能是另一个问题。
    【解决方案2】:

    您的对话动画似乎被 WebView 搞砸的原因是 WebView 内容加载的异步性质。因此,将loadUrlloadData 甚至loadDataWithBaseURL 放在dialog.show() 之前并不能保证内容已经完全加载,即使内容来自本地文件或字符串。仍有轻微延迟(通常为一秒或不到一秒)。

    如果您希望仅在 WebView 内容完全加载后真正显示对话框,则必须在onPageFinishedWebViewClient 中显示对话框。我已经对此进行了测试,并且它在 ICS 上运行良好,但当然,从用户激活对话框和 WebView 内容的可用性开始会有轻微的延迟。如果轻微的延迟没问题,那么这个解决方案可能适合您。

    您可以通过这种方式修改您的代码(更新为包含setWebViewClient):

    WebView myMsg = new WebView(context);
    
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setIcon(R.drawable.ic_launcher);
    builder.setView(myMsg);
    builder.setTitle("Some Title");
    final AlertDialog dialog = builder.create();
    
    // hook a listener for page load complete
    WebViewClient webviewclient = new WebViewClient() {
        @Override  
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            dialog.show(); // show the dialog here
        }
    };
    myMsg.setWebViewClient(webviewclient);
    
    myMsg.loadUrl("file:///android_asset/page.html");
    WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
    lp.windowAnimations = R.style.AnimateDialog;
    
    //dialog.show(); // do not show until content is truly available
    dialog.getWindow().setAttributes(lp);
    

    我已经用我的 Nexus 7 和 Android 4.3 对其进行了测试,但内容的显示仍然会被系统动画时间延迟,就像我在之前的建议中讨论的那样,所以你必须解决我遇到的同样的问题安卓 4.3。

    【讨论】:

    • 是的,我试过onPageFinished(你忘了把WebViewClient附加到WebView,对吧?)。但问题仍然存在。现在Entry 动画根本不起作用,即使使用WindowManager.LayoutParams.FILL_PARENT,除非你把它放在WebViewClient 中。请看一下我原始帖子的编辑,看看唯一使动画有效的东西(但仍然只有WindowManager.LayoutParams.FILL_PARENT 并且仍然是异步的)。知道如何首先禁用默认动画吗?
    • 其实执行Dialog动作后,LogCat最后会显示两行:WebView(17458): onSizeChanged - w:582 h:0WebView(17458): onSizeChanged - w:582 h:708。那么为什么它以 0 高度开始,但以非零宽度开始呢?
    • 啊,是的,当我使用自己的代码时,我忘了复制将 WebViewClient 附加到 WebView 的代码。在我自己的代码中,我实际上使用的是带有 WebView 的 XML 布局,其中 FILL_PARENT 用于 layout_width,WRAP_CONTENT 用于高度,因此我不必在代码中进行设置。你可以尝试做同样的事情吗?设置对话框动画时应该替换默认动画。
    • 关于对话框宽度开始非零而高度为零,我认为这是因为对话框随着内容的长度垂直增长。
    • 或者,在onPageFinished 中,如果您不想将布局放在XML 文件中,可以尝试在布局设置后调用show
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多