Android阴影的方向向下,Android 自定义ShadowBoxLayout 全方向阴影布局

一,可行行分析

上篇《自定义ShadowLayout矢量阴影布局》我们讲过CardView缺陷,本篇是为了解决上一篇全方向的阴影。

f1a130a296e503bc48d46f6ca0bddeb3.png

3ddf867d34bdf57025ad398add44bad2.png

技术方面

这次我们利用MaskFilter实现。

二、关于MaskFilter

一、setMaskFilter(MaskFilter maskfilter)

setMaskFilter(MaskFilter maskfilter)是paint中的方法,它可以用来对图像进行一定的处理。这个方法需要传入一个MaskFilter对象。但MaskFilter类中没有任何实现方法,所以我们就要认识下它的两个子类BlurMaskFilter和EmbossMaskFilter,前者为模糊遮罩滤镜而后者为浮雕遮罩滤镜。

publicBlurMaskFilter(floatradius,Blur style)

float radius:用来定义模糊半径,同样是高斯模糊算法。

Blur style:发光样式,有内发光、外发光、和内外发光,分别对应:Blur.INNER(内发光)、Blur.SOLID(外发光)、Blur.NORMAL(内外发光)、Blur.OUTER(仅发光部分可见),

canvas.drawColor(Color.BLACK);

canvas.drawText("正常",30,100,paint);

Paint paint1 = new Paint();

paint1.setColor(Color.RED);

paint1.setStyle(Paint.Style.FILL);

canvas.drawCircle(300, 100, 50, paint1);

canvas.drawText("INNER",0,250,paint);

Paint paint2 = new Paint();

paint2.setColor(Color.RED);

paint2.setStyle(Paint.Style.FILL);

paint2.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.INNER));

canvas.drawCircle(300, 250, 50, paint2);

canvas.drawText("OUTER",0,400,paint);

Paint paint3 = new Paint();

paint3.setColor(Color.RED);

paint3.setStyle(Paint.Style.FILL);

paint3.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.OUTER));

canvas.drawCircle(300, 400, 50, paint3);

canvas.drawText("NORMAL",0,550,paint);

Paint paint4 = new Paint();

paint4.setColor(Color.RED);

paint4.setStyle(Paint.Style.FILL);

paint4.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL));

canvas.drawCircle(300, 550, 50, paint4);

format,png

同样也可以处理图片

paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));

paint.setColor(Color.GREEN);

canvas.drawBitmap(mBitmap, null, new RectF(100, 100, 100 + mBitmap.getWidth(), mBitmap.getHeight() + 100), paint);

paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));

canvas.drawBitmap(bitmap, null, new RectF(100, 300, 100 + bitmap.getWidth(), bitmap.getHeight() + 300), paint);

format,png

二、ShadowBoxLayout实现

源码文件

public class ShadowBoxLayout extends FrameLayout {

private float mOutLineOffset = 1;

private Paint mShadowPaint;

private int mShadowColor; //阴影颜色

private float mRadius = 1; //阴影转角半径

private RectF mRect = null;

public ShadowBoxLayout(Context context) {

this(context, null);

}

public ShadowBoxLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ShadowBoxLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

if (attrs == null) {

return;

}

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShadowBoxLayout);

mShadowColor = a.getColor(R.styleable.ShadowBoxLayout_shadowBox_color, 0x99333333);

mRadius = a.getDimension(R.styleable.ShadowBoxLayout_shadowBox_radius, 1);

mOutLineOffset = a.getDimension(R.styleable.ShadowBoxLayout_shadowBox_outLineOffset, 1);

if(mRadius<=0){

mRadius = 1;

}

a.recycle();

init();

}

private void init() {

mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mShadowPaint.setColor(mShadowColor);

mShadowPaint.setStyle(Paint.Style.FILL);

mShadowPaint.setAntiAlias(true);

setWillNotDraw(false); //开启viewgroup 绘制模式

setLayerType(LAYER_TYPE_SOFTWARE, null);

int padding = (int) mOutLineOffset;

setPadding(padding,padding,padding,padding);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

int childCount = getChildCount();

if(childCount==0) return;

View view = getChildAt(0);

mRect = new RectF(view.getX(), view.getY(), view.getX() + view.getWidth(), view.getY()+view.getHeight());

}

@Override

public void addView(View child, int index, ViewGroup.LayoutParams params) {

int childCount = getChildCount();

if(childCount>1) throw new RuntimeException("child count > 1 ! ");

super.addView(child, index, params);

}

@Override

protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params) {

int childCount = getChildCount();

if(childCount>1) throw new RuntimeException("child count > 1 ! ");

return super.addViewInLayout(child, index, params);

}

@Override

protected void dispatchDraw(Canvas canvas) {

if(mShadowPaint==null) {

super.dispatchDraw(canvas);

return;

}

mShadowPaint.setMaskFilter(new BlurMaskFilter(mRadius, BlurMaskFilter.Blur.SOLID));

canvas.drawRoundRect(mRect, mRadius, mRadius, mShadowPaint);

super.dispatchDraw(canvas);

}

}

属性文件

使用方法

android:layout_width="wrap_content"

android:layout_height="wrap_content"

app:shadowBox_radius="5dp"

app:shadowBox_color="#99333333"

app:shadowBox_outLineOffset="5dp"

>

android:layout_width="150dp"

android:layout_height="150dp"

android:scaleType="centerCrop"

android:src="@drawable/img_bird" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值