Android开发偷懒技巧之阴影

作者: 闲庭 | 来源:发表于2019-04-20 23:42 被阅读7次

    在Android开发中我们会在设计稿中看到各种阴影效果,我们知道CardView可以添加阴影效果,不过可能并不是我们设计稿想要的效果,那我们如何可以更加灵活地给我们原生控件添加阴影效果,这就是下面所要描述的,当然也可以让设计师给个阴影切图,我们做下.9处理然后使用切图实现阴影效果。
    下面看看如何用代码更灵活地去为原声控件实现阴影效果,源码可以查看 XSelector GitHub, 结尾也会贴出ShadowHelper源码。
    先看效果图:

    shadow.png

    如果使用XSelector工具库,使用方法如下,也可以直接使用该ShadowHelper 类去完成阴影效果。

      XSelector.shadowHelper().setShape(ShadowHelper.SHAPE_CIRCLE)
             .setBgColor(Color.parseColor("#FF3D00"))
             .setShapeRadius(dpToPx(6))
             .setShadowColor(Color.parseColor("#991DE9B6"))
             .setShadowRadius(dpToPx(6))
             .setOffsetX(dpToPx(4))
             .setOffsetY(dpToPx(4))
             .into(textView5);
    

    使用方法存在但不限于上述使用方法,具体详细方法如下:

    模块 方法名 描述
    ShadowHelper setShape 设置背景形状,椭圆或者圆形
    setBgColor 背景颜色
    setShapeRadius 设置背景半径
    setShadeSide 设置阴影方向,默认四周
    setShadeRadius 设置阴影半径
    setShadowColor 设置阴影颜色
    setOffsetX 设置阴影X轴偏移量
    setOffsetY 设置阴影Y轴偏移量
    setShadowAlpha 设置阴影透明度
    into 目标View

    ShadowHelper 源码如下:

    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.ColorFilter;
    import android.graphics.LinearGradient;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.graphics.Shader;
    import android.graphics.drawable.Drawable;
    import android.support.annotation.IntRange;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.view.ViewCompat;
    import android.view.View;
    
    /**
     * 类名称:ShadowHelper
     * 创建者:Create by liujc
     * 创建时间:Create on 2018/5/28
     * 描述:控件阴影效果
     */
    public class ShadowHelper extends Drawable {
    
        static ShadowHelper shadowHelper;
        private Paint mPaint;
        /**
         * 阴影模糊半径,越大越模糊
         */
        private int mShadowRadius;
        /**
         * 阴影颜色
         */
        private int mShadowColor;
        /**
         * 背景形状
         */
        private int mShape;
        /**
         * 背景圆角半径
         */
        private int mShapeRadius;
        /**
         * 阴影x偏移(右偏移)
         */
        private int mOffsetX;
        /**
         * 阴影y偏移(下偏移)
         */
        private int mOffsetY;
        /**
         * 背景颜色
         */
        private int mBgColor[];
        private RectF mRect;
    
        public final static int SHAPE_ROUND = 1;
        public final static int SHAPE_CIRCLE = 2;
        public static final int ALL = 0x1111;
        public static final int LEFT = 0x0001;
        public static final int TOP = 0x0010;
        public static final int RIGHT = 0x0100;
        public static final int BOTTOM = 0x1000;
        /**
         * 阴影边 例:0x1100 表示RIGHT和BOTTOM
         */
        private int shadowSide = ALL;
    
        private ShadowHelper(){
            mShape = ShadowHelper.SHAPE_ROUND;
            mShapeRadius = 0;
            mShadowColor = Color.parseColor("#4d000000");
            mShadowRadius = 18;
            mOffsetX = 0;
            mOffsetY = 0;
            mBgColor = new int[1];
            mBgColor[0] = Color.TRANSPARENT;
    
            mPaint = new Paint();
            mPaint.setColor(Color.TRANSPARENT);
            mPaint.setAntiAlias(true);
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
    
        }
    
        public static ShadowHelper getInstance() {
            shadowHelper = new ShadowHelper();
            return shadowHelper;
        }
    
        public ShadowHelper setShape(int mShape) {
            this.mShape = mShape;
            return this;
        }
    
        public ShadowHelper setShadowSide(int shadowSide) {
            this.shadowSide = shadowSide;
            return this;
        }
    
        public ShadowHelper setShapeRadius(int ShapeRadius) {
            this.mShapeRadius = ShapeRadius;
            return this;
        }
        /**
         * 设置阴影颜色
         * @param shadowColor 例:R.color.colorPrimary
         * @return
         */
        public ShadowHelper setShadowColor(int shadowColor) {
            this.mShadowColor = shadowColor;
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            return this;
        }
    
        /**
         * 设置阴影颜色
         * @param shadowColor 例:#ffffff
         * @return
         */
        public ShadowHelper setShadowColor(String shadowColor) {
            this.mShadowColor = Color.parseColor(shadowColor);
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            return this;
        }
    
        public ShadowHelper setShadowRadius(int shadowRadius) {
            this.mShadowRadius = shadowRadius;
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            return this;
        }
    
        public ShadowHelper setOffsetX(int OffsetX) {
            this.mOffsetX = OffsetX;
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            return this;
        }
    
        public ShadowHelper setOffsetY(int OffsetY) {
            this.mOffsetY = OffsetY;
            mPaint.setShadowLayer(mShadowRadius, mOffsetX, mOffsetY, mShadowColor);
            return this;
        }
    
        /**
         * 设置背景颜色
         * @param BgColor 例:R.color.colorPrimary
         * @return
         */
        public ShadowHelper setBgColor(int BgColor) {
            this.mBgColor[0] = BgColor;
            return this;
        }
    
        /**
         * 设置背景颜色
         * @param bgColor 例:#ffffff
         * @return
         */
        public ShadowHelper setBgColor(String bgColor) {
            this.mBgColor[0] = Color.parseColor(bgColor);
            return this;
        }
    
        public ShadowHelper setBgColor(int[] BgColor) {
            this.mBgColor = BgColor;
            return this;
        }
        public ShadowHelper setBgColor(String[] bgColor) {
            int length = bgColor.length;
            int[] color = new int[length];
            for(int i=0;i < length;i++){
                color[i] = Color.parseColor(bgColor[i]);
            }
            this.mBgColor = color;
            return this;
        }
    
        public ShadowHelper setShadowAlpha(int i) {
            setAlpha(i);
            return this;
        }
    
        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            int leftShadow = (shadowSide & LEFT) == LEFT ? mShadowRadius - mOffsetX : -mShapeRadius;
            int topShadow = (shadowSide & TOP) == TOP ? mShadowRadius - mOffsetY : -mShapeRadius;
            int rightShadow = (shadowSide & RIGHT) == RIGHT ? mShadowRadius + mOffsetX : -mShapeRadius;
            int bottomShadow = (shadowSide & BOTTOM) == BOTTOM ? mShadowRadius + mOffsetY : -mShapeRadius;
            mRect = new RectF(bounds.left + leftShadow, bounds.top + topShadow, bounds.right - rightShadow,
                    bounds.bottom - bottomShadow);
        }
    
        @Override
        public void draw(@NonNull Canvas canvas) {
            Paint newPaint = new Paint();
            if (mBgColor != null) {
                if (mBgColor.length == 1) {
                    newPaint.setColor(mBgColor[0]);
                } else {
                    newPaint.setShader(new LinearGradient(mRect.left, mRect.height() / 2, mRect.right, mRect.height() / 2, mBgColor,
                            null, Shader.TileMode.CLAMP));
                }
            }
            newPaint.setAntiAlias(true);
            if (mShape == SHAPE_ROUND) {
                canvas.drawRoundRect(mRect, mShapeRadius, mShapeRadius, mPaint);
                canvas.drawRoundRect(mRect, mShapeRadius, mShapeRadius, newPaint);
            } else {
                canvas.drawCircle(mRect.centerX(), mRect.centerY(), Math.min(mRect.width(), mRect.height())/ 2, mPaint);
                canvas.drawCircle(mRect.centerX(), mRect.centerY(), Math.min(mRect.width(), mRect.height())/ 2, newPaint);
            }
        }
    
        @Override
        public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
            mPaint.setAlpha(alpha);
        }
    
        @Override
        public void setColorFilter(@Nullable ColorFilter colorFilter) {
            mPaint.setColorFilter(colorFilter);
        }
    
        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }
    
        public static void setShadowHelper(View view, Drawable drawable) {
            view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            ViewCompat.setBackground(view, drawable);
        }
    
        public void into(View view){
            if (view == null){
                return;
            }
            view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            ViewCompat.setBackground(view, this);
        }
    
    }
    

    相关文章

      网友评论

        本文标题:Android开发偷懒技巧之阴影

        本文链接:https://www.haomeiwen.com/subject/eyagwqtx.html