shadow各种调整实现

2018-10-31  本文已影响0人  吉凶以情迁
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);

    }


}

上一篇 下一篇

猜你喜欢

热点阅读