Android 给控件加上阴影

这篇需求———需要动态设置控件的阴影颜色

网上搜了许多,最后定位到ShadowLayout这个控件,使用起来简单,但是只支持圆形和长方形

如果是圆角就不行了

于是再其的基础上做了修改

下面说使用方法

xml调用

<com.luoy.blackdoplanet.common.untils.ShadowLayout
    android:id="@+id/sh_shap"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    app:shadowDx="0dp"
    app:shadowDy="0dp"
    app:shadowShapeRad="26dp"
    app:shadowRadius="4dp"
    app:shadowShape="shap"
    app:shadowSide="all">

    <TextView
        android:id="@+id/tv_com"
        android:layout_width="@dimen/dp90"
        android:layout_height="@dimen/dp26"
        android:gravity="center"
        android:text="去完成"
        android:textColor="@color/white" />
</com.luoy.blackdoplanet.common.untils.ShadowLayout>

需要包含别的控件使用

在attrs中加入

<!-- ShadowLayout 阴影 -->
<declare-styleable name="ShadowLayout">
    <attr name="shadowColor" format="color"/>
    <attr name="shadowRadius" format="dimension"/>
    <attr name="shadowDx" format="dimension"/>
    <attr name="shadowDy" format="dimension"/>
    <attr name="shadowShapeRad" format="dimension"/>
    <attr name="shadowShape">
        <flag name="rectangle" value="0x0001"/>
        <flag name="oval" value="0x0010"/>
        <flag name="shap" value="0x0011"/>
    </attr>
    <attr name="shadowSide">
        <flag name="all" value="0x1111"/>
        <flag name="left" value="0x0001"/>
        <flag name="top" value="0x0010"/>
        <flag name="right" value="0x0100"/>
        <flag name="bottom" value="0x1000"/>
    </attr>
</declare-styleable>

各个属性都很简单

  • app:shadowColor="#66000000" 控制阴影的颜色

  • app:shadowDx="0dp" 控制阴影 x 轴的偏移量

  • app:shadowDy="3dp" 控制阴影 y 轴的偏移量

  • app:shadowRadius="10dp" 控制阴影的范围

  • app:shadowSide="all|left|right|top|bottom" 控制阴影显示的边界,共有五个值

  • shadowShape 阴影的形状

  • shadowShapeRad 圆角的度数

  • shadowColor必须加上透明度

  • 附上代码

  • package com.luoy.blackdoplanet.common.untils;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.view.View;
    import android.widget.RelativeLayout;
    
    import com.botaoweb.blackdoplanet.R;
    
    /**
     * ShadowLayout.java
     * <p>
     * Created by lijiankun on 17/8/11.
     */
    
    public class ShadowLayout extends RelativeLayout {
    
        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;
    
        public static final int SHAPE_RECTANGLE = 0x0001;
    
        public static final int SHAPE_OVAL = 0x0010;
    
        public static final int SHAPE_SHAP = 0x0011;
    
    
        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
        private RectF mRectF = new RectF();
    
        /**
         * 阴影的颜色
         */
        private int mShadowColor = Color.TRANSPARENT;
    
        /**
         * 阴影的大小范围
         */
        private float mShadowRadius = 0;
    
        /**
         * 阴影 x 轴的偏移量
         */
        private float mShadowDx = 0;
    
        /**
         * 阴影 y 轴的偏移量
         */
        private float mShadowDy = 0;
    
        /**
         * 阴影显示的边界
         */
        private int mShadowSide = ALL;
    
        /**
         * 圆角弧度
         */
        private float mShadowShapRad = 0;
    
        /**
         * 阴影的形状,圆形/矩形
         */
        private int mShadowShape = SHAPE_RECTANGLE;
    
        public ShadowLayout(Context context) {
            this(context, null);
        }
    
        public ShadowLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            float effect = mShadowRadius + dip2px(5);
            float rectLeft = 0;
            float rectTop = 0;
            float rectRight = this.getMeasuredWidth();
            float rectBottom = this.getMeasuredHeight();
            int paddingLeft = 0;
            int paddingTop = 0;
            int paddingRight = 0;
            int paddingBottom = 0;
            this.getWidth();
            if ((mShadowSide & LEFT) == LEFT) {
                rectLeft = effect;
                paddingLeft = (int) effect;
            }
            if ((mShadowSide & TOP) == TOP) {
                rectTop = effect;
                paddingTop = (int) effect;
            }
            if ((mShadowSide & RIGHT) == RIGHT) {
                rectRight = this.getMeasuredWidth() - effect;
                paddingRight = (int) effect;
            }
            if ((mShadowSide & BOTTOM) == BOTTOM) {
                rectBottom = this.getMeasuredHeight() - effect;
                paddingBottom = (int) effect;
            }
            if (mShadowDy != 0.0f) {
                rectBottom = rectBottom - mShadowDy;
                paddingBottom = paddingBottom + (int) mShadowDy;
            }
            if (mShadowDx != 0.0f) {
                rectRight = rectRight - mShadowDx;
                paddingRight = paddingRight + (int) mShadowDx;
            }
            mRectF.left = rectLeft;
            mRectF.top = rectTop;
            mRectF.right = rectRight;
            mRectF.bottom = rectBottom;
            this.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
        }
    
        /**
         * 真正绘制阴影的方法
         */
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            setUpShadowPaint();
            if (mShadowShape == SHAPE_RECTANGLE) {
                canvas.drawRect(mRectF, mPaint);
            } else if (mShadowShape == SHAPE_OVAL) {
                canvas.drawCircle(mRectF.centerX(), mRectF.centerY(), Math.min(mRectF.width(), mRectF.height()) / 2, mPaint);
            }else if(mShadowShape == SHAPE_SHAP){
                canvas.drawRoundRect(mRectF, mShadowShapRad, mShadowShapRad,mPaint);//第二个参数是x半径,第三个参数是y半径
            }
        }
    
        public void setShadowColor(int shadowColor) {
            mShadowColor = shadowColor;
            requestLayout();
            postInvalidate();
        }
    
        public void setShadowRadius(float shadowRadius) {
            mShadowRadius = shadowRadius;
            requestLayout();
            postInvalidate();
        }
    
        /**
         * 读取设置的阴影的属性
         *
         * @param attrs 从其中获取设置的值
         */
        private void init(AttributeSet attrs) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);  // 关闭硬件加速
            this.setWillNotDraw(false);                    // 调用此方法后,才会执行 onDraw(Canvas) 方法
    
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ShadowLayout);
            if (typedArray != null) {
                mShadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor,
                        getContext().getResources().getColor(android.R.color.black));
                mShadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius, dip2px(0));
                mShadowDx = typedArray.getDimension(R.styleable.ShadowLayout_shadowDx, dip2px(0));
                mShadowDy = typedArray.getDimension(R.styleable.ShadowLayout_shadowDy, dip2px(0));
                mShadowSide = typedArray.getInt(R.styleable.ShadowLayout_shadowSide, ALL);
                mShadowShape = typedArray.getInt(R.styleable.ShadowLayout_shadowShape, SHAPE_RECTANGLE);
                mShadowShapRad= typedArray.getDimension(R.styleable.ShadowLayout_shadowShapeRad,dip2px(0));
                typedArray.recycle();
            }
            setUpShadowPaint();
        }
    
        private void setUpShadowPaint() {
            mPaint.reset();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.TRANSPARENT);
            mPaint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
        }
    
        /**
         * dip2px dp 值转 px 值
         *
         * @param dpValue dp 值
         * @return px 值
         */
        private float dip2px(float dpValue) {
            DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
            float scale = dm.density;
            return (dpValue * scale + 0.5F);
        }
    }
    
  • demo下载https://download.csdn.net/download/qq_30711091/10596342

猜你喜欢

转载自blog.csdn.net/qq_30711091/article/details/81568228
今日推荐