package com.wpc.library.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.*; import android.graphics.drawable.BitmapDrawable; import android.os.Build; import android.util.AttributeSet; import android.widget.FrameLayout; import com.wpc.lcjianlibrary.R; public class ShadowLayout extends FrameLayout { private int mShadowColor; private float mShadowRadius; private float mCornerRadius; private float mDx; private float mDy; 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) (mShadowRadius + Math.abs(mDx)); int yPadding = (int) (mShadowRadius + Math.abs(mDy)); setPadding(xPadding, yPadding, xPadding, yPadding); } @SuppressWarnings("deprecation") private void setBackgroundCompat(int w, int h) { Bitmap bitmap = createShadowBitmap(w, h, mCornerRadius, mShadowRadius, 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 { mCornerRadius = attr.getDimension(R.styleable.ShadowLayout_sl_cornerRadius, getResources().getDimension(R.dimen.default_corner_radius)); mShadowRadius = attr.getDimension(R.styleable.ShadowLayout_sl_shadowRadius, getResources().getDimension(R.dimen.default_shadow_radius)); mDx = attr.getDimension(R.styleable.ShadowLayout_sl_dx, 0); mDy = attr.getDimension(R.styleable.ShadowLayout_sl_dy, 0); mShadowColor = attr.getColor(R.styleable.ShadowLayout_sl_shadowColor, getResources().getColor(R.color.default_shadow_color)); } 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 output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ALPHA_8); 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; } }