设置属性: <declare-styleable name="ShadowLayout"> <attr name="sfl_backgroundRound" format="dimension" /> <attr name="sfl_shadowWidth" format="dimension" /> <attr name="sfl_shadowColor" format="color" /> <attr name="sfl_background" format="color" /> <attr name="sfl_offsetX" format="dimension" /> <attr name="sfl_offsetY" format="dimension" /> </declare-styleable> 代码实现: public class ShadowLayout extends FrameLayout { private int shadowWidth;//阴影宽度 private int backgroundRound;//背景圆角 private int shadowColor;//阴影颜色 private int backgroundColor;//背景颜色 private int offsetX;//上下偏移(正数上偏移,负数下偏移) private int offsetY;//左右偏移(正数左偏移,负数右偏移) 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); } } private void initView(Context context, AttributeSet attrs) { initAttributes(context, attrs); int xPadding = (int) (shadowWidth + Math.abs(offsetX)); int yPadding = (int) (shadowWidth + Math.abs(offsetY)); setPadding(xPadding, yPadding, xPadding, yPadding); } @SuppressWarnings("deprecation") private void setBackgroundCompat(int w, int h) { Bitmap bitmap = createShadowBitmap(w, h, backgroundRound, shadowWidth, offsetX, offsetY, shadowColor, backgroundColor); 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 (attrs != null) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout); shadowWidth = typedArray.getDimensionPixelSize(R.styleable.ShadowLayout_sfl_shadowWidth, 0); backgroundRound = typedArray.getDimensionPixelSize(R.styleable.ShadowLayout_sfl_backgroundRound, 0); shadowColor = typedArray.getColor(R.styleable.ShadowLayout_sfl_shadowColor, Color.parseColor("#ffffff")); backgroundColor = typedArray.getColor(R.styleable.ShadowLayout_sfl_background, Color.parseColor("#ffffff")); offsetX = typedArray.getDimensionPixelSize(R.styleable.ShadowLayout_sfl_offsetX, 0); offsetY = typedArray.getDimensionPixelSize(R.styleable.ShadowLayout_sfl_offsetY, 0); typedArray.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 output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ARGB_8888); 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; } }
带阴影布局
最新推荐文章于 2021-11-02 18:38:25 发布