在这几周Android Design in Action episode期间,Adam Koch谈到了一款名为Etsy的应用程序,该应用程序具有这种非常酷的模糊效果,适用于导航抽屉拉出时的主要布局。
有谁知道Etsy背后的开发者是如何实现这一目标的呢?
在此处观看:http://youtu.be/GjUxEddmjFw?t=22m48s
答案 0 :(得分:67)
这有几个部分:
1。创建模糊位图:
当抽屉首次打开时,我们从抽屉后面的内容视图创建缩小尺寸的位图(缩小使模糊快速)。然后我们使用RenderScript将模糊应用于缩小尺寸的图像(更快)。为此,您应该阅读已经提到的博客http://nicolaspomepuy.fr/?p=18并查看GlassActionBar项目以获取参考代码https://github.com/ManuelPeinado/GlassActionBar。
注意: RenderScript is now available in the support library ...但无法使用Gradle构建(目前为止)。此外,某些设备(尤其是Nexus 10)上存在ScriptIntrinsicBlur的问题 - 请参阅Roman Nurik's explanation
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" />
在Activities 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来自NineOldAndroids,所以我们可以在蜂窝前设置alpha()。
答案 1 :(得分:4)
查看此博客http://nicolaspomepuy.fr/?p=18
基本上,您可以从原始图像生成模糊图像。我想在这种情况下,原始版本是使用getDrawingCache()
方法生成的,请务必先调用setDrawingCacheEnabled()
。