package cn.ijiami.safekeyboard.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import junit.framework.Assert;
/**
* Created by qssq on 2018/6/25 qssq666@foxmail.com
*/
public class ShadowHelper {
private static final String TAG = "ShadowHelper";
private final View view;
private double alpha=1.0;
public void setCircle(boolean circle) {
this.circle = circle;
}
private boolean circle = false;
private final Paint paint;
/**
* 圆角矩形或者绘制圆形的shadow图形
*/
private int rectShadowRadius = 2;
Builder getTarget() {
return target;
}
private Builder target;
public boolean isHasShadow() {
return hasShadow;
}
private boolean hasShadow;
public void setShadowLayer(float radius, float dx, float dy, int shadowColor) {
setShadowLayer(radius, dx, dy, shadowColor, true);
}
public void setShadowLayer(float radius, float dx, float dy, int shadowColor, boolean invalidate) {
if ((dx > 0 || dy > 0) && shadowColor != 0) {
this.hasShadow = true;
target.dx = dx;
target.dy = dy;
target.shadowColor = shadowColor;
this.shadowPaint.setShadowLayer(radius, dx, dy, shadowColor);
this.shadowPaint.setColor(target.rectColor);
this.shadowPaint.setAlpha((int) (alpha*255));
// this.shadowPaint.setStrokeWidth(dx);
}
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (invalidate) {
postInvalidate();
}
//
}
public void postInvalidate() {
view.postInvalidate();
}
public void setDrawRectRadius(int radius) {
this.rectShadowRadius = radius;//如果处理的是有圆角的,那么真绘制的应该也是圆角,否则会显示绘制的区域,如绘制颜色是黑色,会导致有黑色.
}
public View getView() {
return view;
}
public void setTarget(Builder target) {
this.target = target;
}
public Paint getCreatePaint() {
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setAntiAlias(true);
return paint;
}
public void setAlpha(double alpha) {
if(alpha<=0){
alpha=1.0f;
}
this.alpha = alpha;
}
public static class Builder {
private int rectColor = Color.CYAN;
public Builder setCircleRdius(float circleRdius) {
this.circleRdius = circleRdius;
return this;
}
public float circleRdius;
public Builder() {
}
public Builder setRadius(int radius) {
this.radius = radius;
return this;
}
public Builder setDx(int dx) {
this.dx = dx;
return this;
}
public Builder setDy(int dy) {
this.dy = dy;
return this;
}
public float getDrawXStart() {
return dx;
}
public float getDrawXEnd(int width) {
return width - (dx * 2);
}
public float getDrawYStart() {
return dy;
}
public float getDrawyEnd(int height) {
return height - (dy * 2);
}
public Builder setShadowColor(int shadowColor) {
this.shadowColor = shadowColor;
return this;
}
int radius;
float dx;
float dy;
int shadowColor;
public ShadowHelper build(Context context, View view) {
ShadowHelper shadowHelper = new ShadowHelper(context, view);
shadowHelper.setTarget(this);
// view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
// shadowHelper.setShadowLayer(radius, dx, dy, shadowColor);
if (dx > 0 || dy > 0 && shadowColor != 0) {
shadowHelper.setShadowLayer(radius, dx, dy, shadowColor);//need create to set
}
return shadowHelper;
}
public void setRectColor(int rectColor) {
this.rectColor = rectColor;
}
}
public Paint getShadowPaint() {
return shadowPaint;
}
private final Paint shadowPaint;
ShadowHelper(Context context, View view) {
this.view = view;
shadowPaint = new Paint();
shadowPaint.setColor(Color.TRANSPARENT);
shadowPaint.setStyle(Paint.Style.FILL);
// shadowPaint.setStyle(Paint.Style.STROKE);
shadowPaint.setStrokeWidth(1);
// shadowPaint.setAntiAlias(true);//去除锯齿。
// shadowPaint.setDither(true);//饱满
// shadowPaint.setStrokeCap(Paint.Cap.ROUND);
paint = new Paint();
paint.setColor(Color.CYAN);
}
private Bitmap drawableToBitamp(Drawable drawable) {
return drawableToBitamp(drawable, 694, 886);
}
/**
* @param drawable
* @param defaultWidth
* @param defaultHeight
* @return
*/
public Bitmap drawableToBitamp(Drawable drawable, int defaultWidth, int defaultHeight) {
System.out.println("Drawable转Bitmap");
Bitmap bitmap;
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {//color drawable
bitmap = Bitmap.createBitmap(defaultWidth, defaultHeight, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_4444);
}
//注意,下面三行代码要用到,否在在View或者surfaceview里的canvas.drawBitmap会看不到图
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public void onDraw(Canvas canvas, View view) {
if (hasShadow) {
int scaleWidth = (int) (view.getMeasuredWidth() - target.dx);
int scaleHeight = (int) (view.getMeasuredHeight() - target.dy);
Drawable background = view.getBackground();
if (background != null) {
if (background instanceof BitmapDrawable) {
((BitmapDrawable) background).getPaint().setColor(Color.RED);
}
background.setBounds(0, 0, scaleWidth, scaleHeight);
view.invalidate();
//https://developer.android.com/guide/topics/graphics/drawables
}
Assert.assertTrue(target.dx > 0);
Assert.assertTrue(target.dy > 0);
int deleteSize = (int) (shadowPaint.getStrokeWidth() / 2);
canvas.drawLine(scaleWidth - deleteSize, 0, scaleWidth - deleteSize, scaleHeight, shadowPaint);//绘制垂直线然后产生阴影 绘制xd的中心点非左边所以要/2
//垂直线实现阴影会发现阴影高度没那么多;.
// canvas.drawLine(0, scaleHeight/2, scaleWidth - deleteSize, scaleHeight-shadowPaint.getStrokeWidth(), shadowPaint);
canvas.drawRect(new Rect(0, (int) (scaleHeight - getShadowPaint().getStrokeWidth()), scaleWidth, scaleHeight), shadowPaint);
}
}
public void onDraw1(Canvas canvas, View view, Drawable drawable) {
if (hasShadow) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
int scaleWidth = (int) (view.getMeasuredWidth() - target.dx);
int scaleHeight = (int) (view.getMeasuredHeight() - target.dy);
Assert.assertTrue(target.dx > 0);
Assert.assertTrue(target.dy > 0);
int deleteSize = (int) (shadowPaint.getStrokeWidth() / 2);
canvas.drawLine(scaleWidth - deleteSize, 0, scaleWidth - deleteSize, scaleHeight, shadowPaint);//绘制垂直线然后产生阴影 绘制xd的中心点非左边所以要/2
//垂直线实现阴影会发现阴影高度没那么多;.
// canvas.drawLine(0, scaleHeight/2, scaleWidth - deleteSize, scaleHeight-shadowPaint.getStrokeWidth(), shadowPaint);
//后面为什么要-为了避免香蕉的地方太浓
if (circle) {
canvas.drawCircle(scaleHeight / 2, scaleWidth / 2, target.circleRdius, shadowPaint);
} else {
RectF rect = new RectF(0, scaleHeight - getShadowPaint().getStrokeWidth(), scaleWidth - getShadowPaint().getStrokeWidth(), scaleHeight);
canvas.drawRoundRect(rect, target.radius, target.radius, shadowPaint);
}
}
if (hasShadow) {
drawBitmap(canvas, view, drawable, paint);
}
}
public void onDrawShadowAndPicBg(Canvas canvas, View view, Drawable drawable) {
Paint paint = drawShadow(canvas, view);
/* if (true) {
return;
}*/
drawBitmap(canvas, view, drawable, ((int) target.dx), ((int) target.dy), paint, false);
}
public void drawShadow(Canvas canvas, int x,int y,float btnWidth,float btnHeight) {
if (circle) {
canvas.drawCircle(x+(btnWidth/2), x+(btnHeight/2), rectShadowRadius, shadowPaint);
} else {
RectF rectF = new RectF(x,y, x+btnWidth, y+btnHeight);
canvas.drawRoundRect(rectF, rectShadowRadius, rectShadowRadius,shadowPaint);
}
}
public Paint drawShadow(Canvas canvas, View view) {
int scaleWidth = (int) target.getDrawXEnd(view.getMeasuredWidth());
int scaleHeight = (int) target.getDrawyEnd(view.getMeasuredHeight());
if (circle) {
canvas.drawCircle(scaleWidth / 2, scaleHeight / 2, rectShadowRadius, shadowPaint);
} else {
RectF rectF = new RectF(target.getDrawXStart(), target.getDrawYStart(), scaleWidth, scaleHeight);
canvas.drawRoundRect(rectF, rectShadowRadius, rectShadowRadius, shadowPaint);
}
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setAntiAlias(true);
return paint;
}
public void onDrawShadowAndBg3(Canvas canvas, View view, Drawable drawable) {
int scaleWidth = (int) target.getDrawXEnd(view.getMeasuredWidth());
int scaleHeight = (int) target.getDrawyEnd(view.getMeasuredHeight());
if (circle) {
canvas.drawCircle(scaleWidth / 2, scaleHeight / 2, rectShadowRadius, shadowPaint);
} else {
RectF rectF = new RectF(target.getDrawXStart(), target.getDrawYStart(), scaleWidth, scaleHeight);
canvas.drawRoundRect(rectF, rectShadowRadius, rectShadowRadius, shadowPaint);
}
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setAntiAlias(true);
drawBitmap(canvas, view, drawable, ((int) target.dx), ((int) target.dy), paint, true);
}
/**
* 禁止拉伸
*
* @param canvas
* @param view
* @param drawable
*/
public void onDrawImgBg(Canvas canvas, View view, Drawable drawable) {
int scaleWidth = (int) target.getDrawXEnd(view.getMeasuredWidth());
int scaleHeight = (int) target.getDrawyEnd(view.getMeasuredHeight());
if (circle) {
canvas.drawCircle(scaleWidth / 2, scaleHeight / 2, rectShadowRadius, shadowPaint);
} else {
RectF rectF = new RectF(target.getDrawXStart(), target.getDrawYStart(), scaleWidth, scaleHeight);
canvas.drawRoundRect(rectF, rectShadowRadius, rectShadowRadius, shadowPaint);
}
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setAntiAlias(true);
/* if (true) {
return;
}*/
drawBitmap(canvas, view, drawable, ((int) target.dx), ((int) target.dy), paint, true);
}
private void drawBitmap(Canvas canvas, View view, Drawable drawable, Paint paint) {
drawBitmap(canvas, view, drawable, 0, 0, paint, false);
}
public void drawBitmap(Canvas canvas, View view, Drawable drawable, int left, int top, Paint paint, boolean isPic) {
if (drawable == null) {
return;
}
// canvas.save();
int scaleWidth = (int) (view.getMeasuredWidth() - (target.dx * 2));
int scaleHeight = (int) (view.getMeasuredHeight() - (target.dy * 2));
Rect rect = new Rect(0, 0, scaleWidth, scaleHeight);
canvas.clipRect(rect);
isPic = drawable.getIntrinsicHeight() > 0;
int boundWidth = Math.min(isPic ? drawable.getIntrinsicWidth() : scaleWidth, scaleWidth);
int boundHeight = Math.min(isPic ? drawable.getIntrinsicHeight() : scaleHeight, scaleHeight);
int startX = 0;
int startY = 0;
if (isPic) {//不能比view区域大同时也不能把图片强制拉伸到这个区域.。
int chaWidth = scaleWidth - boundWidth;
int chaHeight = scaleHeight - boundHeight;
if (chaWidth == 0) {
startX = 0;
} else {
startX = chaWidth / 2;
}
if (chaHeight == 0) {
startY = 0;
} else {
startY = chaHeight / 2;
}
}
drawable.setBounds(0, 0, boundWidth, boundHeight);
if (drawable.isStateful()) {
int[] state = view.getDrawableState();
drawable.setState(state);
}else{
// Log.w(TAG,"STATE FULL FALSE");
}
if (startX == 0 && startY == 0) {
drawable.draw(canvas);
} else {
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else {
bitmap = drawableToBitamp(drawable, scaleWidth, scaleHeight);
}
canvas.drawBitmap(bitmap, startX, startY, paint);
}
}
@Deprecated
public void onDraw(Canvas canvas, View view, View parent) {
if (hasShadow) {
// Builder target = this.getTarget();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (int) (parent.getMeasuredWidth() - target.dx);
layoutParams.height = (int) (parent.getMeasuredWidth() - target.dy);
int top = view.getTop();
int bottom = view.getBottom();
int right = view.getRight();
// Log.w(TAG, "top:" + top + ",bottom:" + bottom + ",right:" + right + "");
RectF rect = new RectF(view.getLeft(), view.getTop(), layoutParams.width, layoutParams.height);
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
canvas.drawRect(rect, shadowPaint);
canvas.drawRect(new Rect(0, 0, 80, 80), shadowPaint);
}
}
/**
* 设置时透明通道也会影响阴影的的透明度
*
* @param color
*/
public void setBackgroundColor(int color) {
shadowPaint.setColor(color);
target.rectColor = color;
}
public void clearShadowLayer() {
shadowPaint.clearShadowLayer();
this.hasShadow = false;
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
网友评论