Java 硬件加速的webview滑入动画在IC上闪烁

Java 硬件加速的webview滑入动画在IC上闪烁,java,android,Java,Android,我们的应用程序大量使用Web视图。在IC上测试时,我们注意到需要设置应用程序属性hardwareAccelerated=“true”。然而,这样做会在我们的应用程序中导致一些其他错误,其中大部分我们已经修复。我们仍然无法让“滑入”动画正常工作。在没有任何代码更改的情况下,动画只是执行“显示”类型的动画,而不是滑动。我们尝试了几种不同的方法: 添加一个小的alpha转换(.99->1)。这会将“显示”更改为“幻灯片”,但有时会导致屏幕上出现一些奇怪的瑕疵 在动画期间使用硬件层。这并不总是有效的 在

我们的应用程序大量使用Web视图。在IC上测试时,我们注意到需要设置应用程序属性
hardwareAccelerated=“true”
。然而,这样做会在我们的应用程序中导致一些其他错误,其中大部分我们已经修复。我们仍然无法让“滑入”动画正常工作。在没有任何代码更改的情况下,动画只是执行“显示”类型的动画,而不是滑动。我们尝试了几种不同的方法:

  • 添加一个小的alpha转换(.99->1)。这会将“显示”更改为“幻灯片”,但有时会导致屏幕上出现一些奇怪的瑕疵
  • 在动画期间使用硬件层。这并不总是有效的
  • 在动画期间使用软件层。这是可行的,但会在首次完成滑入动画后导致缓慢的重画
  • 方法3是最有希望的,但我们还没有找到避免重画的方法。我们使用带有单个活动的示例项目创建了一个小测试用例:

    活动类别:

        int accelValue = View.LAYER_TYPE_NONE; //hack
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        addClickListenerAnimation(R.id.buttonhl, R.anim.to_left, View.VISIBLE, View.INVISIBLE);
        addClickListenerAnimation(R.id.buttonhr, R.anim.to_right, View.VISIBLE, View.INVISIBLE);
        addClickListenerAnimation(R.id.buttonsl, R.anim.from_left, View.INVISIBLE, View.VISIBLE);
        addClickListenerAnimation(R.id.buttonsr, R.anim.from_right, View.INVISIBLE, View.VISIBLE);
    
        final Button b = (Button) findViewById(R.id.accel);
        b.setOnClickListener(
                             new View.OnClickListener()
                            {
                                @Override
                                public void onClick(View v)
                                {
                                    accelValue = ++accelValue % 3;
                                    b.setText(accelValue == 0 ? "NONE" : accelValue == 1 ? "S/W" : "H/W");
                                }
                            });
    
    }
    
    private void addClickListenerAnimation(int buttonId, final int animId, final int startVis, final int endVis)
    {
        Button b = (Button) findViewById(buttonId);
        b.setOnClickListener(
         new View.OnClickListener()
        {
    
            @Override
            public void onClick(View v)
            {
                final WebView wv = (WebView) findViewById(R.id.webview);
                final View layout = findViewById(R.id.frame);
                Animation a = AnimationUtils.loadAnimation(getApplicationContext(), animId);
    
                a.setDuration(500);
    
                a.setAnimationListener(new AnimationListener()
                {
    
                    @Override
                    public void onAnimationStart(Animation animation)
                    {
                        Log.i("sb", "layer type was " + wv.getLayerType());
                        Log.i("sb", "llayout layer type was " + layout.getLayerType());
                        wv.setLayerType(accelValue, null);
                        Log.i("sb", "setting layer type " + accelValue);
                    }
    
                    @Override
                    public void onAnimationRepeat(Animation animation)
                    {
                    }
    
                    @Override
                    public void onAnimationEnd(Animation animation)
                    {
                        wv.setLayerType(View.LAYER_TYPE_NONE, null);
                        Log.i("sb", "restoring layout layer type " + layout.getLayerType());
                    }
                });
    
                layout.setAnimation(a);
                layout.setVisibility(endVis);
            }
        });
    }
    
    @Override
    protected void onStart()
    {
        super.onStart();
        ((WebView)findViewById(R.id.webview)).loadUrl("http://www.wikipedia.org");
    }
    
    从_left.xml动画(其他动画xml类似):

    
    
    main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/llayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
    <FrameLayout 
                android:id="@+id/frame"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:visibility="invisible"
        >
            <WebView
                android:id="@+id/webview"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"/>
    </FrameLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="80dp"
            android:background="#FF000000" />
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="80dp"
            android:orientation="horizontal" >
    
            <Button
                android:id="@+id/buttonsl"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:text="show L" />
    
            <Button
                android:id="@+id/buttonhl"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:text="hide L" />
    
            <Button
                android:id="@+id/buttonsr"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:text="show R" />
    
            <Button
                android:id="@+id/buttonhr"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:text="hide R" />
    
            <Button
                android:id="@+id/accel"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:text="NONE" />
        </LinearLayout>
    
    </LinearLayout>
    
    
    
    舱单:

    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.INTERNET" />
    

    好吧,如果您试图支持ICS及以后的产品,您可以使用新的动画API,因为它们更易于使用,而且我相信会非常流畅

    这里有两个链接可以查看此API:

    如果您想在旧版本中使用此API,请尝试

    编辑:尝试将
    网络视图的层设置为软件层:

        web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    

    它停止了闪烁,但在视图中失去了硬件加速。我不确定,但我猜对于动画之类的东西,视图仍然会被认为具有硬件加速,因为它的“容器”仍然具有硬件加速功能。但我也可能完全错了。

    它对我来说很好用

    web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    

    闪烁的问题已经解决了

    从您的描述来看,这似乎是我遇到的同一个问题,尽管我不能完全确定这一点。起初我使用了你的解决方案,但现在我有了一个效果更好的解决方案。我只是简单地设置

    android:alwaysDrawnWithCache="true"
    
    在web视图上。这就消除了所有闪烁和错误的绘图


    我希望有帮助

    ObjectAnimator也有同样的问题。我认为这是一个android bug,与动画+网络视图+硬件加速有关。我想知道是否有人找到了解决办法。我明白了。我在这里做了一个小测试,可以确认即使使用新的API也会发生这种情况。将图层强制为软件确实解决了问题,请参阅我的编辑,如果这对您有帮助。是的,这将解决闪烁问题,但是webview中的滚动性能变得不可接受-这是我们启用硬件加速的主要原因之一。。。似乎动画结束时调用将层类型恢复为“无”会导致闪烁。然后我认为问题在于WebView的内容。在我的Nexus S上,我几乎可以打开任何没有滚动性能问题的网站。但我不这样做,根据android文档,如果你的应用程序是硬件加速的,这个标志没有任何效果。我猜你的应用程序处于s/w模式…web.setLayerType(View.LAYER\u TYPE\u SOFTWARE,null);webview.setBackgroundColor(0);
    android:alwaysDrawnWithCache="true"