硬件加速webview幻灯片动画在ICS上闪烁

时间:2012-02-03 17:23:22

标签: java android

我们的应用程序大量使用webview。在ICS上进行测试时,我们注意到我们需要设置应用程序属性hardwareAccelerated="true"。但是,这样做会导致我们的应用程序中出现一些其他错误,其中大部分已修复。我们仍然无法让“滑入式”动画工作。没有任何代码更改,动画只会执行“揭示”类型动画而不是滑动。我们尝试了一些不同的东西:

  1. 添加小的alpha转换(.99-> 1)。这会将“揭示”更改为“幻灯片”,但有时会在屏幕上造成一些奇怪的瑕疵。
  2. 在动画期间使用硬件图层。这不能始终如一地工作。
  3. 在动画期间使用软件图层。这可行,但在第一次完成幻灯片动画后会导致缓慢重绘。
  4. 方法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");
    }
    

    from_left.xml动画(其他动画xmls类似):

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:shareInterpolator="true">
        <translate  android:fromXDelta="-100%" 
                    android:toXDelta="0%" 
                    android:fromYDelta="0%"
                    android:toYDelta="0%" 
                    android:duration="600" 
                    android:zAdjustment="bottom" 
                    />
    </set>
    

    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" />
    

3 个答案:

答案 0 :(得分:7)

好吧,如果您正在尝试支持ICS及以后版本,您可以使用新的动画API,因为它们更容易使用,我相信会非常顺利。

以下是两个链接,可以查看此API:

thisthis

如果您想将此API用于旧版本,请尝试使用NineOldAndroids

修改:尝试将WebView的图层设置为软件图层:

    web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

它停止了闪烁但你在视图中丢失了硬件加速。我不确定,但我想,对于像动画这样的东西,视图仍然被视为具有硬件加速,因为它的“容器”仍然存在。但我也可能完全错了。

答案 1 :(得分:3)

使用

对我来说很好
web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

闪烁的问题已经解决了

答案 2 :(得分:0)

从你的描述来看,这似乎与我遇到的问题相同,尽管我并不完全确定。起初我使用了你的解决方案,但现在我有一个更好的工作。我只是设置

android:alwaysDrawnWithCache="true"

在网络视图上。这可以摆脱所有闪烁和错误的绘画。

我希望它有所帮助!