对话动画搞砸了webview:android bug?

时间:2013-07-30 03:08:25

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

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

使用下面的代码(没有webview),对话框可以完美地工作,在Enter和Exit处设置动画。但是,如果我取消注释 行//builder.setView(myMsg),退出动画仍然完美,但不执行输入动画(或执行速度太快)。有趣的是,如果我最小化应用程序并再次将其最大化,则可以正确执行“输入”对话框动画。

就像webview加载混乱输入动画一样。我尝试在加载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

我刚刚意识到使用TextView TextView.setText(Html.fromHTML...)代替WebView时会出现同样的问题。此外,如果我在 dialog.getWindow().setLayout(600,800)之后添加dialog.show() ,则会按预期执行动画。所以似乎问题是如果事先不知道对话框大小就不会执行动画?

2 个答案:

答案 0 :(得分:0)

我有类似的问题,但我没有动画,我想禁用它,因为它搞乱了我的Dialog与WebView的明显加载时间。我实际上能够禁用主窗口动画Enter / Exit,因为它不再淡入/淡出但问题是WebView的内容大部分时间是由Dialog的Slide动画延迟,我也试图禁用(我真的认为如果禁用窗口动画,则应禁用所有动画。)

根据我的测试,这实际上是一个Jellybean bug,但它在Android 4.3中最为明显,额外的动画会弄乱我的弹出窗口。但是ICS没有问题。

如果您尝试通过Android设置增加默认动画时间 - &gt;开发者选项 - &gt;窗口动画比例,比如5或甚至10,您会注意到内容现在甚至在显示时进一步延迟。但是如果关闭动画,显示速度会很快。我相信如果禁用默认动画,您的动画也可能会起作用。

我认为这种行为是一个Jelly bean bug,只有在Dialog中使用WebView时才会出现这种情况。该对话框在动画时间之后放置WebView内容,即使它已经被禁用,因为它在高度增长时滑动它。

我尝试的另一个解决方案是缓存Dialog,以便可以重复使用它。我的问题消失了,但有时候没有正确调整实际的HTML内容。现在,如果您的内容在显示时的长度大致相同,则可能只需缓存对话框。

我希望我能给你很多线索。

答案 1 :(得分:0)

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

如果您想在 之后真正显示对话框 ,那么WebView内容已完全加载,您必须在onPageFinished WebViewClient内显示对话框1}}。我已经对此进行了测试,并且它与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);

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