【Android开发】毛玻璃效果

使用一:静态控件上使用

image1

  1. 先附上自定义view-BlurringView
public class BlurringView extends View {

   private int mDownsampleFactor;
   private int mOverlayColor;
   private View mBlurredView;
   private int mBlurredViewWidth, mBlurredViewHeight;
   private boolean mDownsampleFactorChanged;
   private Bitmap mBitmapToBlur, mBlurredBitmap;
   private Canvas mBlurringCanvas;
   private RenderScript mRenderScript;
   private ScriptIntrinsicBlur mBlurScript;
   private Allocation mBlurInput, mBlurOutput;

   public BlurringView(Context context) {
       this(context, null);
   }

   public BlurringView(Context context, AttributeSet attrs) {
       super(context, attrs);

       final Resources res = getResources();
       final int defaultBlurRadius = res.getInteger(R.integer.default_blur_radius);
       final int defaultDownsampleFactor = res.getInteger(R.integer.default_downsample_factor);
       final int defaultOverlayColor = res.getColor(R.color.default_overlay_color);

       initializeRenderScript(context);

       TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PxBlurringView);
       setBlurRadius(a.getInt(R.styleable.PxBlurringView_blurRadius, defaultBlurRadius));
       setDownsampleFactor(a.getInt(R.styleable.PxBlurringView_downsampleFactor,
               defaultDownsampleFactor));
       setOverlayColor(a.getColor(R.styleable.PxBlurringView_overlayColor, defaultOverlayColor));
       a.recycle();
   }

   public void setBlurredView(View blurredView) {
       mBlurredView = blurredView;
   }

   @Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
       if (mBlurredView != null) {
           if (prepare()) {
               // If the background of the blurred view is a color drawable, we use it to clear
               // the blurring canvas, which ensures that edges of the child views are blurred
               // as well; otherwise we clear the blurring canvas with a transparent color.
               if (mBlurredView.getBackground() != null && mBlurredView.getBackground() instanceof ColorDrawable) {
                   mBitmapToBlur.eraseColor(((ColorDrawable) mBlurredView.getBackground()).getColor());
               } else {
                   mBitmapToBlur.eraseColor(Color.TRANSPARENT);
               }

               mBlurredView.draw(mBlurringCanvas);
               blur();

               canvas.save();
               canvas.translate(mBlurredView.getX() - getX(), mBlurredView.getY() - getY());
               canvas.scale(mDownsampleFactor, mDownsampleFactor);
               canvas.drawBitmap(mBlurredBitmap, 0, 0, null);
               canvas.restore();
           }
           canvas.drawColor(mOverlayColor);
       }
   }

   public void setBlurRadius(int radius) {
       mBlurScript.setRadius(radius);
   }

   public void setDownsampleFactor(int factor) {
       if (factor <= 0) {
           throw new IllegalArgumentException("Downsample factor must be greater than 0.");
       }

       if (mDownsampleFactor != factor) {
           mDownsampleFactor = factor;
           mDownsampleFactorChanged = true;
       }
   }

   public void setOverlayColor(int color) {
       mOverlayColor = color;
   }

   private void initializeRenderScript(Context context) {
       mRenderScript = RenderScript.create(context);
       mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript));
   }

   protected boolean prepare() {
       final int width = mBlurredView.getWidth();
       final int height = mBlurredView.getHeight();

       if (mBlurringCanvas == null || mDownsampleFactorChanged
               || mBlurredViewWidth != width || mBlurredViewHeight != height) {
           mDownsampleFactorChanged = false;

           mBlurredViewWidth = width;
           mBlurredViewHeight = height;

           int scaledWidth = width / mDownsampleFactor;
           int scaledHeight = height / mDownsampleFactor;

           // The following manipulation is to avoid some RenderScript artifacts at the edge.
           scaledWidth = scaledWidth - scaledWidth % 4 + 4;
           scaledHeight = scaledHeight - scaledHeight % 4 + 4;

           if (mBlurredBitmap == null
                   || mBlurredBitmap.getWidth() != scaledWidth
                   || mBlurredBitmap.getHeight() != scaledHeight) {
               mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight,
                       Bitmap.Config.ARGB_8888);
               if (mBitmapToBlur == null) {
                   return false;
               }

               mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight,
                       Bitmap.Config.ARGB_8888);
               if (mBlurredBitmap == null) {
                   return false;
               }
           }

           mBlurringCanvas = new Canvas(mBitmapToBlur);
           mBlurringCanvas.scale(1f / mDownsampleFactor, 1f / mDownsampleFactor);
           mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur,
                   Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
           mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType());
       }
       return true;
   }

   protected void blur() {
       mBlurInput.copyFrom(mBitmapToBlur);
       mBlurScript.setInput(mBlurInput);
       mBlurScript.forEach(mBlurOutput);
       mBlurOutput.copyTo(mBlurredBitmap);
   }

   @Override
   protected void onDetachedFromWindow() {
       super.onDetachedFromWindow();
       if (mRenderScript != null) {
           mRenderScript.destroy();
       }
   }
}
  1. 调用自定义view
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#FFFFFFFF"
   tools:context=".SecondActivity">

   <ImageView android:id="@+id/iv_blur"
       android:src="@mipmap/image5"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:scaleType="fitXY"/>

   <com.example.maoboli.maobolidemo.BlurringView
       android:id="@+id/blurring_view"
       android:layout_width="260dp"
       android:layout_height="200dp"
       android:layout_gravity="center"
       android:layout_marginBottom="80dip"
       app:blurRadius="20"
       app:downsampleFactor="6"
       app:overlayColor="#26FFFFFF"/>

   <Button
       android:id="@+id/shuffle_button"
       android:layout_width="100dp"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:layout_marginBottom="120dp"
       android:text="模糊头像"/>

   <Button
       android:id="@+id/suibian"
       android:layout_width="100dp"
       android:layout_height="wrap_content"
       android:layout_below="@id/shuffle_button"
       android:layout_gravity="center"
       android:layout_marginTop="30dp"
       android:layout_marginBottom="80dip"
       android:text="随便点"/>

</FrameLayout>
  1. 编辑activity
      BlurringView mBlurringView = (BlurringView) findViewById(R.id.blurring_view);
      View  blurredView = findViewById(R.id.iv_blur);
       // Give the blurring view a reference to the blurred view.
       mBlurringView.setBlurredView(blurredView);

使用二:模糊头像效果

image2

  1. 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">

   <RelativeLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <ImageView android:id="@+id/iv_blur"
           android:layout_width="match_parent"
           android:layout_height="200dp" />

       <ImageView android:id="@+id/iv_avatar"
           android:layout_width="60dp"
           android:layout_height="60dp"
           android:scaleType="fitCenter"
           android:layout_centerInParent="true"/>

   </RelativeLayout>

</LinearLayout>
  1. 编辑activity
public class MainActivity extends AppCompatActivity {

   private ImageView blurImageView;
   private ImageView avatarImageView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       findViews();
       initData();
   }

   private void findViews(){
       blurImageView = (ImageView) findViewById(R.id.iv_blur);
       avatarImageView = (ImageView) findViewById(R.id.iv_avatar);
   }

   private void initData(){
       Glide.with(this).load(R.mipmap.image)
               .bitmapTransform(new BlurTransformation(this, 30), new CenterCrop(this))
               .into(blurImageView);

       Glide.with(this).load(R.mipmap.image)
               .bitmapTransform(new CropCircleTransformation(this))
               .into(avatarImageView);
   }
}
  1. 导包
   compile 'com.github.bumptech.glide:glide:3.7.0'
   compile 'jp.wasabeef:glide-transformations:2.0.1'

使用三:弹出模糊对话框

image3

具体代码参考git上的 Demo

posted @ 2018-12-27 15:08  浪里小白龙呼呼呼  阅读(7507)  评论(0编辑  收藏  举报