5

スライドイン ナビゲーション (Facebook、Path、または Google+ Android アプリ) を実装しようとしています。このバグを再現するための完全なソースは、ここにあります

ただし、デバイス上で画面外にアニメートすると、画面から押し出す直前にWebViewデバイスが噛み付いているかのように、ちらつきが発生します。WebView

WebView スライド ナビゲーション メニュー IN (デバイス)

エミュレータ上ではアーティファクトは発生しません!アニメーションはスムーズに進行します。

WebView スライド ナビゲーション メニュー IN (エミュレーター)

興味深いことに、このちらつきは、アニメーション化されているビューがWebView! メイン コンテンツ ビューとして TextView を使用する同じプロジェクトを次に示します。

TextView スライド ナビゲーション メニュー IN (デバイス)

Web ビュー アクティビティのレイアウト:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue" >

    <WebView
        android:id="@+id/web_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

テキスト ビュー アクティビティの場合:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue" >

    <TextView
        android:id="@+id/web_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello there. no flicker!"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
         />

</RelativeLayout>

ナビゲーション メニューをスライドさせるために呼び出されるコード:

 private void slideIn() {
        LinearLayout actionBarFrame = (LinearLayout) findViewById(android.R.id.content).getParent();

        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        menuView = inflater.inflate(R.layout.menu, null);
        menuView.setLayoutParams(new FrameLayout.LayoutParams(SIZE, LayoutParams.MATCH_PARENT, Gravity.LEFT));
        FrameLayout decorView = (FrameLayout) getWindow().getDecorView();
        decorView.addView(menuView);
        decorView.bringChildToFront(actionBarFrame);

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) actionBarFrame.getLayoutParams();
        params.setMargins(SIZE, 0, -SIZE, 0);
        actionBarFrame.setLayoutParams(params);

        TranslateAnimation ta = new TranslateAnimation(-SIZE, 0, 0, 0);
        ta.setDuration(DURATION); 
        actionBarFrame.startAnimation(ta);
    }

スライドして戻すには:

    private void slideOut() {
        LinearLayout actionBarFrame = (LinearLayout) findViewById(android.R.id.content).getParent();

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) actionBarFrame.getLayoutParams();
        params.setMargins(0, 0, 0, 0);
        actionBarFrame.setLayoutParams(params);

        TranslateAnimation ta = new TranslateAnimation(SIZE, 0, 0, 0);
        ta.setDuration(DURATION);
        ta.setAnimationListener(new  AnimationListener() {
            @Override 
            public void onAnimationEnd(Animation arg0) {
                ((FrameLayout) getWindow().getDecorView()).removeView(menuView);
                menuView = null;
            }
            @Override public void onAnimationRepeat(Animation arg0) { }
            @Override public void onAnimationStart(Animation arg0) { }
        });
        actionBarFrame.startAnimation(ta);
    }

コードをパブリック リポジトリとしてBitBucketにアップロードしたので、このプロジェクトを私とまったく同じように試すことができます。

これがなぜ起こっているのか、またはそれを修正する方法についての助けやアイデアは大歓迎です! WebView求められているのは、アウトオブザピクチャとバックインをスムーズにアニメーション化することです。ありがとうございます!

4

1 に答える 1

7

一般的に言えば、問題はWebViews3.0 以降のデバイスでハードウェア アクセラレーションを有効にして使用する場合のバグに関係しているようです。また、スライド メニューライブラリを使用してみましたWebViewが、同じちらつきの問題が発生しました。周りを見回した後、ここで回避策を見つけました:

ハードウェア アクセラレーションが有効な場合、WebView が白い背景で「点滅」する (Android 3.0 以降)

この回避策では、次のコードを使用して、 のレイヤ タイプWebViewをソフトウェア レンダリングに設定します。

webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

このコードは、ちらつきを解決しましたが、パフォーマンスが低下するという欠点がありました。

于 2013-04-24T08:51:14.600 に答える