|
@@ -54,34 +54,34 @@ public class BlurView extends View {
|
|
|
private View mDecorView;
|
|
|
private boolean mDifferentRoot;
|
|
|
private static int RENDERING_COUNT;
|
|
|
-
|
|
|
+
|
|
|
private Paint mPaint;
|
|
|
private RectF mRectF;
|
|
|
-
|
|
|
+
|
|
|
public BlurView(Context context, AttributeSet attrs) {
|
|
|
super(context, attrs);
|
|
|
init(context, attrs);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public BlurView(Context context) {
|
|
|
super(context);
|
|
|
-
|
|
|
+
|
|
|
init(context, null);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public BlurView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
|
super(context, attrs, defStyleAttr);
|
|
|
-
|
|
|
+
|
|
|
init(context, attrs);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private boolean isInit = false;
|
|
|
-
|
|
|
+
|
|
|
Paint cutPaint;
|
|
|
Paint overlayPaint;
|
|
|
-
|
|
|
+
|
|
|
private void init(Context context, AttributeSet attrs) {
|
|
|
- if (!isInit) {
|
|
|
+ if (!isInit && context != null) {
|
|
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RealtimeBlurView);
|
|
|
mBlurRadius = a.getDimension(
|
|
|
R.styleable.RealtimeBlurView_realtimeBlurRadius,
|
|
@@ -89,24 +89,24 @@ public class BlurView extends View {
|
|
|
);
|
|
|
mDownsampleFactor = a.getFloat(R.styleable.RealtimeBlurView_realtimeDownsampleFactor, 4);
|
|
|
mOverlayColor = a.getColor(R.styleable.RealtimeBlurView_realtimeOverlayColor, 0x00ffffff);
|
|
|
-
|
|
|
+
|
|
|
//ready rounded corner
|
|
|
mPaint = new Paint();
|
|
|
mPaint.setAntiAlias(true);
|
|
|
mRectF = new RectF();
|
|
|
-
|
|
|
+
|
|
|
cutPaint = new Paint();
|
|
|
cutPaint.setAntiAlias(true);
|
|
|
cutPaint.setColor(mOverlayColor);
|
|
|
-
|
|
|
+
|
|
|
overlayPaint = new Paint();
|
|
|
overlayPaint.setAntiAlias(true);
|
|
|
-
|
|
|
+
|
|
|
mRadius = a.getDimension(R.styleable.RealtimeBlurView_realtimeRadius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, context.getResources().getDisplayMetrics()));
|
|
|
a.recycle();
|
|
|
-
|
|
|
+
|
|
|
isInit = true;
|
|
|
-
|
|
|
+
|
|
|
if (!isCompatMode()) {
|
|
|
setOutlineProvider(new ViewOutlineProvider() {
|
|
|
@Override
|
|
@@ -118,11 +118,11 @@ public class BlurView extends View {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private boolean isCompatMode() {
|
|
|
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void setBlurRadius(float radius) {
|
|
|
if (mBlurRadius != radius) {
|
|
|
mBlurRadius = radius;
|
|
@@ -130,7 +130,7 @@ public class BlurView extends View {
|
|
|
invalidate();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void setRadiusPx(float r) {
|
|
|
if (mRadius != r) {
|
|
|
mRadius = r;
|
|
@@ -138,12 +138,12 @@ public class BlurView extends View {
|
|
|
invalidate();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void setDownsampleFactor(float factor) {
|
|
|
if (factor <= 0) {
|
|
|
throw new IllegalArgumentException("Downsample factor must be greater than 0.");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (mDownsampleFactor != factor) {
|
|
|
mDownsampleFactor = factor;
|
|
|
mDirty = true; // may also change blur radius
|
|
@@ -151,14 +151,14 @@ public class BlurView extends View {
|
|
|
invalidate();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public void setOverlayColor(int color) {
|
|
|
if (mOverlayColor != color) {
|
|
|
mOverlayColor = color;
|
|
|
invalidate();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private void releaseBitmap() {
|
|
|
if (mBlurInput != null) {
|
|
|
mBlurInput.destroy();
|
|
@@ -177,7 +177,7 @@ public class BlurView extends View {
|
|
|
mBlurredBitmap = null;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private void releaseScript() {
|
|
|
if (mRenderScript != null) {
|
|
|
mRenderScript.destroy();
|
|
@@ -188,27 +188,27 @@ public class BlurView extends View {
|
|
|
mBlurScript = null;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected void release() {
|
|
|
releaseBitmap();
|
|
|
releaseScript();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected boolean prepare() {
|
|
|
if (mBlurRadius == 0) {
|
|
|
release();
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
float downsampleFactor = mDownsampleFactor;
|
|
|
-
|
|
|
+
|
|
|
if (mDirty || mRenderScript == null) {
|
|
|
if (supportRenderScript && useBlur) {
|
|
|
if (mRenderScript == null) {
|
|
|
try {
|
|
|
mRenderScript = RenderScript.create(getContext());
|
|
|
mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript));
|
|
|
-
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
supportRenderScript = false;
|
|
|
if (isDebug()) {
|
|
@@ -216,7 +216,7 @@ public class BlurView extends View {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
mDirty = false;
|
|
|
float radius = mBlurRadius / downsampleFactor;
|
|
|
if (radius > 25) {
|
|
@@ -226,16 +226,16 @@ public class BlurView extends View {
|
|
|
if (mBlurScript != null) mBlurScript.setRadius(radius);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
final int width = getWidth();
|
|
|
final int height = getHeight();
|
|
|
-
|
|
|
+
|
|
|
int scaledWidth = Math.max(1, (int) (width / downsampleFactor));
|
|
|
int scaledHeight = Math.max(1, (int) (height / downsampleFactor));
|
|
|
-
|
|
|
+
|
|
|
if (mBlurringCanvas == null || mBlurredBitmap == null || mBlurredBitmap.getWidth() != scaledWidth || mBlurredBitmap.getHeight() != scaledHeight) {
|
|
|
releaseBitmap();
|
|
|
-
|
|
|
+
|
|
|
boolean r = false;
|
|
|
try {
|
|
|
mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
|
|
@@ -243,21 +243,21 @@ public class BlurView extends View {
|
|
|
return false;
|
|
|
}
|
|
|
mBlurringCanvas = new Canvas(mBitmapToBlur);
|
|
|
-
|
|
|
+
|
|
|
if (!supportRenderScript || !useBlur) {
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur,
|
|
|
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT
|
|
|
);
|
|
|
mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType());
|
|
|
-
|
|
|
+
|
|
|
mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
|
|
|
if (mBlurredBitmap == null) {
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
r = true;
|
|
|
} catch (Exception e) {
|
|
|
if (isDebug()) e.printStackTrace();
|
|
@@ -270,14 +270,14 @@ public class BlurView extends View {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected void blur(Bitmap bitmapToBlur, Bitmap blurredBitmap) {
|
|
|
mBlurInput.copyFrom(bitmapToBlur);
|
|
|
mBlurScript.setInput(mBlurInput);
|
|
|
mBlurScript.forEach(mBlurOutput);
|
|
|
mBlurOutput.copyTo(blurredBitmap);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
|
|
|
@Override
|
|
|
public boolean onPreDraw() {
|
|
@@ -289,13 +289,13 @@ public class BlurView extends View {
|
|
|
decor.getLocationOnScreen(locations);
|
|
|
int x = -locations[0];
|
|
|
int y = -locations[1];
|
|
|
-
|
|
|
+
|
|
|
getLocationOnScreen(locations);
|
|
|
x += locations[0];
|
|
|
y += locations[1];
|
|
|
|
|
|
mBitmapToBlur.eraseColor(mOverlayColor & 0xffffff);
|
|
|
-
|
|
|
+
|
|
|
int rc = mBlurringCanvas.save();
|
|
|
mIsRendering = true;
|
|
|
RENDERING_COUNT++;
|
|
@@ -313,18 +313,18 @@ public class BlurView extends View {
|
|
|
RENDERING_COUNT--;
|
|
|
mBlurringCanvas.restoreToCount(rc);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
blur(mBitmapToBlur, mBlurredBitmap);
|
|
|
-
|
|
|
+
|
|
|
if (redrawBitmap || mDifferentRoot) {
|
|
|
invalidate();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
protected void onAttachedToWindow() {
|
|
|
super.onAttachedToWindow();
|
|
@@ -351,7 +351,7 @@ public class BlurView extends View {
|
|
|
mDifferentRoot = false;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
protected void onDetachedFromWindow() {
|
|
|
if (mDecorView != null) {
|
|
@@ -360,13 +360,13 @@ public class BlurView extends View {
|
|
|
release();
|
|
|
super.onDetachedFromWindow();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
public void draw(Canvas canvas) {
|
|
|
if (!useBlur || !supportRenderScript) {
|
|
|
mRectF.right = getWidth();
|
|
|
mRectF.bottom = getHeight();
|
|
|
- overlayPaint.setColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor): mOverlayColor);
|
|
|
+ overlayPaint.setColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor) : mOverlayColor);
|
|
|
canvas.drawRoundRect(mRectF, mRadius, mRadius, overlayPaint);
|
|
|
} else {
|
|
|
if (!mIsRendering && RENDERING_COUNT <= 0) {
|
|
@@ -374,7 +374,7 @@ public class BlurView extends View {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
protected void onDraw(Canvas canvas) {
|
|
|
super.onDraw(canvas);
|
|
@@ -384,7 +384,7 @@ public class BlurView extends View {
|
|
|
drawBlurredBitmap(canvas, mBlurredBitmap);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private void drawBlurredBitmapCompat(Canvas canvas) {
|
|
|
if (mBlurredBitmap != null) {
|
|
|
mRectDst.right = getWidth();
|
|
@@ -403,7 +403,7 @@ public class BlurView extends View {
|
|
|
if (overlyBitmap != null) canvas.drawBitmap(overlyBitmap, 0, 0, null);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap) {
|
|
|
if (blurredBitmap != null) {
|
|
|
mRectSrc.right = blurredBitmap.getWidth();
|
|
@@ -411,13 +411,13 @@ public class BlurView extends View {
|
|
|
mRectDst.right = getWidth();
|
|
|
mRectDst.bottom = getHeight();
|
|
|
canvas.drawBitmap(blurredBitmap, mRectSrc, mRectDst, null);
|
|
|
- canvas.drawColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor): mOverlayColor);
|
|
|
+ canvas.drawColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor) : mOverlayColor);
|
|
|
} else {
|
|
|
Bitmap overlyBitmap = drawOverlyColor(Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888));
|
|
|
if (overlyBitmap != null) canvas.drawBitmap(overlyBitmap, 0, 0, null);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private Bitmap getRoundedCornerBitmap(Bitmap bitmap, Rect mRectDst) {
|
|
|
bitmap = drawOverlyColor(resizeImage(bitmap, mRectDst.width(), mRectDst.height()));
|
|
|
if (bitmap == null) return null;
|
|
@@ -430,7 +430,7 @@ public class BlurView extends View {
|
|
|
canvas.drawRoundRect(new RectF(mRectDst), mRadius, mRadius, paint);
|
|
|
return output;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private Bitmap drawOverlyColor(Bitmap bitmap) {
|
|
|
if (bitmap != null) {
|
|
|
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
|
@@ -438,13 +438,13 @@ public class BlurView extends View {
|
|
|
Rect originRect = new Rect();
|
|
|
originRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
|
|
canvas.drawBitmap(bitmap, originRect, originRect, overlayPaint);
|
|
|
- canvas.drawColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor): mOverlayColor);
|
|
|
+ canvas.drawColor(needRemoveAlphaColor() ? removeAlphaColor(mOverlayColor) : mOverlayColor);
|
|
|
return output;
|
|
|
} else {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private Bitmap resizeImage(Bitmap bitmap, int newWidth, int newHeight) {
|
|
|
if (bitmap != null) {
|
|
|
int width = bitmap.getWidth();
|
|
@@ -458,24 +458,24 @@ public class BlurView extends View {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static boolean supportRenderScript = false;
|
|
|
private boolean useBlur = true;
|
|
|
-
|
|
|
+
|
|
|
public boolean isUseBlur() {
|
|
|
return useBlur;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public BlurView setUseBlur(boolean useBlur) {
|
|
|
this.useBlur = useBlur;
|
|
|
invalidate();
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- private boolean needRemoveAlphaColor(){
|
|
|
- if (overrideOverlayColor){
|
|
|
+ private boolean needRemoveAlphaColor() {
|
|
|
+ if (overrideOverlayColor) {
|
|
|
return false;
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
return !(supportRenderScript && useBlur);
|
|
|
}
|
|
|
}
|
|
@@ -494,7 +494,7 @@ public class BlurView extends View {
|
|
|
int blue = Color.blue(color);
|
|
|
return Color.argb(alpha, red, green, blue);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
static {
|
|
|
/**
|
|
|
* 之所以需要启动一个新线程检测RenderScript是否可用的原因是不清楚Android什么时候对loadClass做了变更,
|
|
@@ -516,23 +516,23 @@ public class BlurView extends View {
|
|
|
}
|
|
|
}.start();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static boolean DEBUGMODE = false;
|
|
|
-
|
|
|
+
|
|
|
static boolean isDebug() {
|
|
|
return DEBUGMODE && DialogX.DEBUGMODE;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static void log(Object o) {
|
|
|
if (isDebug()) Log.i(">>>", "DialogX.BlurView: " + o.toString());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static void error(Object o) {
|
|
|
if (isDebug()) Log.e(">>>", o.toString());
|
|
|
}
|
|
|
|
|
|
public BlurView setOverrideOverlayColor(boolean overrideOverlayColor) {
|
|
|
- log("setOverrideOverlayColor: "+overrideOverlayColor);
|
|
|
+ log("setOverrideOverlayColor: " + overrideOverlayColor);
|
|
|
this.overrideOverlayColor = overrideOverlayColor;
|
|
|
return this;
|
|
|
}
|