31

今週のAndroid Design in Action エピソードで、Adam Koch はEtsyというアプリについて話しました。このアプリは、Navigation Drawer が引き出されたときにメイン レイアウトに適用される非常にクールなぼかし効果を特徴としていました。

Etsy の背後にいる開発者がこれをどのように実装したか知っている人はいますか?

こちらでご覧ください: http://youtu.be/GjUxEddmjFw?t=22m48s

ここに画像の説明を入力 ここに画像の説明を入力

4

2 に答える 2

67

これにはいくつかの部分があります。

1. ぼやけたビットマップの作成:

ドロワーが最初に開かれたときに、ドロワーの背後にあるコンテンツ ビューから縮小されたビットマップを作成します (縮小するとぼかしが速くなります)。次に、可能な場合は RenderScript を使用して (さらに高速に)、縮小した画像にぼかしを適用します。これについては、既に言及されているブログhttp://nicolaspomepuy.fr/?p=18を読み、参照コードhttps://github.com/ManuelPeinado/GlassActionBarの GlassActionBar プロジェクトをチェックアウトする必要があります。

注: RenderScript はサポート ライブラリで利用できるようになりましたが、Gradle を使用してビルドすることはできません (今のところ)。また、一部のデバイス、特に Nexus 10ではScriptIntrinsicBlurに問題があります- Roman Nurik の説明を参照してください

2. ぼかしの表示とアニメーション化:

ナビゲーション ドロワー レイアウトには、コンテンツの上にある非表示の ImageView が含まれています。

<FrameLayout
    android:id="@+id/nav_content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- our blur image -->
<ImageView
    android:id="@+id/blur_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:visibility="gone" />

アクティビティ onCreate() で、この ImageView への参照を取得し、カスタム ドロワー リスナーをセットアップします。

mBlurImage = (ImageView) findViewById(R.id.blur_image);
mDrawerLayout = (DrawerLayout) findViewById(R.id.nav_drawer_layout);

mDrawerToggle = new EtsyNavActionBarDrawerToggle(
            this, 
            mDrawerLayout,
            R.drawable.ic_drawer, 
            R.string.nav_drawer_open, 
            R.string.nav_drawer_closed);

mDrawerLayout.setDrawerListener(mDrawerToggle);

私たちの引き出しには、デフォルトの透明な黒ではなく、カスタム スクリム カラー (オーバーレイ カラー) があります。これにより、ぼやけた画像が縮小された画像上にあるという事実も隠されます。

mDrawerLayout.setScrimColor(getResources().getColor(R.color.background_main_v2_glass));

ぼやけた画像を設定、クリア、およびアニメーション化するドロワー リスナー:

private class EtsyNavActionBarDrawerToggle extends ActionBarDrawerToggle {

    public EtsyNavActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, 
            int drawerImageRes, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
        super(activity, drawerLayout, drawerImageRes, openDrawerContentDescRes, closeDrawerContentDescRes);
    }

    @Override
    public void onDrawerSlide(final View drawerView, final float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);
        if (slideOffset > 0.0f) {
            setBlurAlpha(slideOffset);
        }
        else {
            clearBlurImage();
        }
    }

    @Override
    public void onDrawerClosed(View view) {
        clearBlurImage();
    }

}

private void setBlurAlpha(float slideOffset) {
    if (mBlurImage.getVisibility() != View.VISIBLE) {
        setBlurImage();
    }
    ViewHelper.setAlpha(mBlurImage, slideOffset);
}

public void setBlurImage() {
    mBlurImage.setImageBitmap(null);
    mBlurImage.setVisibility(View.VISIBLE);
    Bitmap downScaled = ... // do the downscaling
    Bitmap blurred = ... // apply the blur
    mBlurImage.setImageBitmap(blurred);
}

public void clearBlurImage() {
    mBlurImage.setVisibility(View.GONE);
    mBlurImage.setImageBitmap(null);
}

最後に、ViewHelper は NineOldAndroid からのものであるため、setAlpha() を事前にハニカムにすることができます。

于 2013-12-03T22:28:56.317 に答える
4

このブログをご覧くださいhttp://nicolaspomepuy.fr/?p=18

基本的に、元の画像からぼかし画像を生成します。この場合、元のメソッドはメソッドを使用して生成されていると思います。getDrawingCache()必ずsetDrawingCacheEnabled()最初に呼び出してください。

于 2013-11-28T19:03:44.547 に答える