美文网首页
自定义阴影Layout

自定义阴影Layout

作者: BayRoc | 来源:发表于2020-12-08 18:23 被阅读0次

    一个自定义阴影的Layout

    同样是因为项目暂时告一段落,在此记录一下!(因为要实现一个根据主题色改变阴影颜色的Layout,因此打包不同的项目,主题色是不固定的,所以需要动态设置颜色)

    以下代码转自https://github.com/yangchong211/YCCardView,自己只是稍稍做了处理
    /**
     * author: roc
     * time: 12/7/20 7:16 PM
     * explain: 引用自--https://github.com/yangchong211/YCCardView
     */
    public class ShadowLayout extends FrameLayout {
    
        /**
         * 阴影颜色
         */
        private int mShadowColor;
        /**
         * 阴影的扩散范围(也可以理解为扩散程度)
         */
        private float mShadowLimit;
        /**
         * 阴影的圆角大小
         */
        private float mCornerRadius;
        /**
         * x轴的偏移量
         */
        private float mDx;
        /**
         * y轴的偏移量
         */
        private float mDy;
        /**
         * 左边是否显示阴影
         */
        private boolean leftShow;
        /**
         * 右边是否显示阴影
         */
        private boolean rightShow;
        /**
         * 上边是否显示阴影
         */
        private boolean topShow;
        /**
         * 下面是否显示阴影
         */
        private boolean bottomShow;
        /**
         * 阴影透明度
         */
        private float transparentValue;
    
    
        private boolean mInvalidateShadowOnSizeChanged = true;
        private boolean mForceInvalidateShadow = false;
    
        public ShadowLayout(Context context) {
            super(context);
            initView(context, null);
        }
    
        public ShadowLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView(context, attrs);
        }
    
        public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(context, attrs);
        }
    
        @Override
        protected int getSuggestedMinimumWidth() {
            return 0;
        }
    
        @Override
        protected int getSuggestedMinimumHeight() {
            return 0;
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            if (w > 0 && h > 0 && (getBackground() == null || mInvalidateShadowOnSizeChanged
                    || mForceInvalidateShadow)) {
                mForceInvalidateShadow = false;
                setBackgroundCompat(w, h);
            }
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            if (mForceInvalidateShadow) {
                mForceInvalidateShadow = false;
                setBackgroundCompat(right - left, bottom - top);
            }
        }
    
        public void setInvalidateShadowOnSizeChanged(boolean invalidateShadowOnSizeChanged) {
            mInvalidateShadowOnSizeChanged = invalidateShadowOnSizeChanged;
        }
    
        public void invalidateShadow() {
            mForceInvalidateShadow = true;
            requestLayout();
            invalidate();
        }
    
        private void initView(Context context, AttributeSet attrs) {
            initAttributes(context, attrs);
    
            int xPadding = (int) (mShadowLimit + Math.abs(mDx));
            int yPadding = (int) (mShadowLimit + Math.abs(mDy));
            int left;
            int right;
            int top;
            int bottom;
            if (leftShow) {
                left = xPadding;
            } else {
                left = 0;
            }
    
            if (topShow) {
                top = yPadding;
            } else {
                top = 0;
            }
    
    
            if (rightShow) {
                right = xPadding;
            } else {
                right = 0;
            }
    
            if (bottomShow) {
                bottom = yPadding;
            } else {
                bottom = 0;
            }
    
            setPadding(left, top, right, bottom);
        }
    
        @SuppressWarnings("deprecation")
        private void setBackgroundCompat(int w, int h) {
            Bitmap bitmap = createShadowBitmap(w, h, mCornerRadius, mShadowLimit, mDx,
                    mDy, mShadowColor, Color.TRANSPARENT);
            BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap);
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
                setBackgroundDrawable(drawable);
            } else {
                setBackground(drawable);
            }
        }
    
    
        private void initAttributes(Context context, AttributeSet attrs) {
            TypedArray attr = getTypedArray(context, attrs, R.styleable.ShadowLayout);
            if (attr == null) {
                return;
            }
    
            try {
                //默认是显示
                leftShow = attr.getBoolean(R.styleable.ShadowLayout_yc_leftShow, true);
                rightShow = attr.getBoolean(R.styleable.ShadowLayout_yc_rightShow, true);
                bottomShow = attr.getBoolean(R.styleable.ShadowLayout_yc_bottomShow, true);
                topShow = attr.getBoolean(R.styleable.ShadowLayout_yc_topShow, true);
    
                mCornerRadius = attr.getDimension(R.styleable.ShadowLayout_yc_cornerRadius, 0);
                mShadowLimit = attr.getDimension(R.styleable.ShadowLayout_yc_shadowLimit, 0);
                mDx = attr.getDimension(R.styleable.ShadowLayout_yc_dx, 0);
                mDy = attr.getDimension(R.styleable.ShadowLayout_yc_dy, 0);
                transparentValue = attr.getFloat(R.styleable.ShadowLayout_yc_transparent, 0.3f);
                String tempColor = BaseUtils.toHexEncoding(attr.getColor(R.styleable.ShadowLayout_yc_shadowColor,
                        getResources().getColor(R.color.colorAccount)));
                mShadowColor = Color.parseColor("#" + convertTransparency(transparentValue) + tempColor);
            } finally {
                attr.recycle();
            }
        }
    
        private TypedArray getTypedArray(Context context, AttributeSet attributeSet, int[] attr) {
            return context.obtainStyledAttributes(attributeSet, attr, 0, 0);
        }
    
        private Bitmap createShadowBitmap(int shadowWidth, int shadowHeight, float cornerRadius,
                                          float shadowRadius, float dx, float dy,
                                          int shadowColor, int fillColor) {
    
            //根据宽高创建bitmap背景
            Bitmap output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ARGB_8888);
            //用画板canvas进行绘制
            Canvas canvas = new Canvas(output);
            RectF shadowRect = new RectF(shadowRadius, shadowRadius,
                    shadowWidth - shadowRadius, shadowHeight - shadowRadius);
    
            if (dy > 0) {
                shadowRect.top += dy;
                shadowRect.bottom -= dy;
            } else if (dy < 0) {
                shadowRect.top += Math.abs(dy);
                shadowRect.bottom -= Math.abs(dy);
            }
    
            if (dx > 0) {
                shadowRect.left += dx;
                shadowRect.right -= dx;
            } else if (dx < 0) {
                shadowRect.left += Math.abs(dx);
                shadowRect.right -= Math.abs(dx);
            }
    
            Paint shadowPaint = new Paint();
            shadowPaint.setAntiAlias(true);
            shadowPaint.setColor(fillColor);
            shadowPaint.setStyle(Paint.Style.FILL);
            if (!isInEditMode()) {
                shadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor);
            }
            canvas.drawRoundRect(shadowRect, cornerRadius, cornerRadius, shadowPaint);
            return output;
        }
    
        /**
         * 将透明度数值转换为String
         *
         * @param value
         * @return
         */
        private String convertTransparency(float value) {
            if (value == 0) {
                return "00";
            } else if (value == 0.1f) {
                return "1A";
            } else if (value == 0.2f) {
                return "33";
            } else if (value == 0.3f) {
                return "4D";
            } else if (value == 0.4f) {
                return "66";
            } else if (value == 0.5f) {
                return "80";
            } else if (value == 0.6f) {
                return "99";
            } else if (value == 0.7f) {
                return "B3";
            } else if (value == 0.8f) {
                return "CC";
            } else if (value == 0.9f) {
                return "E6";
            } else if (value == 1.0f) {
                return "FF";
            } else
                return "00";
        }
    }
    

    attr资源

    <!-- 自定义阴影layout -->
        <declare-styleable name="ShadowLayout">
            <!--阴影的圆角大小-->
            <attr name="yc_cornerRadius" format="dimension" />
            <!--阴影的扩散范围(也可以理解为扩散程度)-->
            <attr name="yc_shadowLimit" format="dimension" />
            <!--阴影颜色-->
            <attr name="yc_shadowColor" format="color" />
            <!--x轴的偏移量-->
            <attr name="yc_dx" format="dimension" />
            <!--y轴的偏移量-->
            <attr name="yc_dy" format="dimension" />
            <!--左边是否显示阴影-->
            <attr name="yc_leftShow" format="boolean" />
            <!--右边是否显示阴影-->
            <attr name="yc_rightShow" format="boolean" />
            <!--上边是否显示阴影-->
            <attr name="yc_topShow" format="boolean" />
            <!--下面是否显示阴影-->
            <attr name="yc_bottomShow" format="boolean" />
            <!-- 阴影透明度 -->
            <attr name="yc_transparent" format="float" />
        </declare-styleable>
    

    使用方式:

    <!-- 此layout中只能有一个子View -->
     <app.wangxiao.cn.view.ShadowLayout
                        android:layout_width="match_parent"
                        android:layout_height="100dp"
                        android:layout_gravity="center_horizontal"
                        android:layout_marginStart="15dp"
                        android:layout_marginEnd="15dp"
                        app:yc_cornerRadius="10dp"
                        app:yc_dx="0dp"
                        app:yc_dy="0dp"
                        app:yc_shadowColor="@color/colorAccount"
                        app:yc_shadowLimit="5dp"
                        app:yc_transparent="0.1">
    
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:background="@color/white"
                            android:gravity="center">
                            
                            <!-- 此处为layout内容 -->
                            
                        </LinearLayout>
    </app.wangxiao.cn.view.ShadowLayout>
    

    相关文章

      网友评论

          本文标题:自定义阴影Layout

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