2012-02-03 45 views
3

我們的應用程序大量使用webviews。在ICS上進行測試時,我們注意到我們需要設置應用程序屬性hardwareAccelerated="true"。但是,這樣做會在我們的應用程序中導致一些其他錯誤,其中大部分我們已經修復。我們仍然有問題讓我們的「滑入式」動畫工作。如果沒有任何代碼更改,動畫只會執行「顯示」類型的動畫而不是滑動。我們嘗試了幾個不同的東西:在ICS上硬件加速的webview幻燈片動畫閃爍

  1. 添加一個小的alpha轉換(.99-> 1)。這會將「揭示」更改爲「幻燈片」,但有時會在屏幕上產生一些奇怪的痕跡。
  2. 在動畫過程中使用硬件層。這不一致。
  3. 在動畫過程中使用軟件層。這可以起作用,但在滑入動畫首次完成後導致緩慢重繪。

方法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動畫(其他動畫個XML是相似的):

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

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

回答

7

好吧,如果您嘗試支持ICS並繼續使用,您可以使用新的動畫API,因爲它們更容易使用,我相信會非常流暢。

這裏是看看這個API兩個鏈接:

thisthis

如果你想使用這個API的舊版本,嘗試NineOldAndroids

編輯:嘗試將WebView的圖層設置爲軟件一:

web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

它停止了閃爍,但您在視圖內部失去了硬件加速。我不確定,但我想對於像動畫這樣的東西,視圖仍然會被視爲硬件加速,因爲它的「容器」仍然存在。但我也可能完全錯誤。

+1

ObjectAnimator有同樣的問題。我認爲這是一個android動畫+ webviews +硬件加速的bug。我想知道是否有人找到解決方法。 – slushi 2012-02-03 17:52:14

+0

我明白了。我在這裏做了一個小測試,可以確認即使使用新的API也會發生。強制圖層成爲軟件確實解決了問題,請參閱我的編輯,是否可以幫助您。 – 2012-02-03 18:22:50

+0

是的,這將解決閃爍問題,但在web視圖中的滾動性能變得不可接受 - 這是我們將硬件加速轉換爲的主要原因之一......看起來像在動畫結束時調用以恢復圖層類型到NONE導致閃爍。 – slushi 2012-02-03 19:07:44

3

它使用

web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

閃爍的問題得到了解決

+0

web.setLayerType(View.LAYER_TYPE_SOFTWARE,null); webview.setBackgroundColor(0); Harsha 2014-09-24 11:52:27

+0

其工作像我一樣沒有flikkering – Harsha 2014-09-24 11:53:45

0

從你的描述好像這是同一個問題我有,但我不能完全肯定這工作對我罰款。起初我用你的解決方案,但現在我有一個更好的工作。我簡單地設置

android:alwaysDrawnWithCache="true" 

在網頁上查看。這將擺脫所有閃爍和錯誤的繪圖。

我希望它有幫助!

+0

沒有爲我工作,也根據android文檔,這個標誌沒有任何效果,如果你的應用程序是硬件加速。我的猜測是你離開你的應用程序在S/W模式... – slushi 2012-06-09 23:05:05