其实实现阴影Android系统自带android:elevation实现阴影功能,但是在低版本系统可能就无效了,当然还可以使用shape.xml实现,CardView也可以实行阴影功能,但是尴尬的是不知道怎么切换阴影的颜色。
上图中图一是使用setShadowLayer实现的阴影效果
上图中图二是使用 setMaskFilter(new BlurMaskFilter(50,BlurMaskFilter.Blur.SOLID));
- 实现图一完整代码
定义几个属性
<declare-styleable name="ShadowLayerView">
<attr name="elevate" format="integer"/>
<attr name="elevationColor" format="color"/>
<attr name="shape" format="enum">
<enum name="shapeRect" value="1"/>
<enum name="circle" value="2"/>
<enum name="round" value="3"/>
</attr>
<attr name="roundRx" format="integer"/>
<attr name="roundRy" format="integer"/>
</declare-styleable>
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import com.jewelermobile.gangfu.zdydemo1.R;
public class ShadowLayerView extends View {
/**阴影*/
private int elevation;
/**阴影的颜色*/
private int elevationColor;
/**view的形状*/
private int shape = 1;
private static final int shapeRect = 1 ;
private static final int circle = 2 ;
private static final int round = 3 ;
/**圆角 x轴半径*/
private int roundRx ;
/**圆角 y轴半径*/
private int roundRy ;
public ShadowLayerView(Context context) {
this(context,null);
}
public ShadowLayerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public ShadowLayerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.ShadowLayerView,0,defStyleAttr);
int count = array.getIndexCount();
for (int i = 0 ; i<count ; i++){
int attr = array.getIndex(i);
switch (attr){
case R.styleable.ShadowLayerView_elevate:
elevation = array.getInt(attr,20);
break;
case R.styleable.ShadowLayerView_elevationColor:
elevationColor = array.getColor(attr,Color.RED);
break;
case R.styleable.ShadowLayerView_shape:
shape = array.getInt(attr,shapeRect);
break;
case R.styleable.ShadowLayerView_roundRx:
roundRx = array.getInt(attr,0);
break;
case R.styleable.ShadowLayerView_roundRy:
roundRy = array.getInt(attr,0);
break;
}
}
array.recycle();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeWidth(10);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
paint.setShadowLayer(elevation,0,0,elevationColor);
Rect rect=new Rect(getPaddingLeft(),getPaddingTop(),getWidth()-getPaddingRight(),getBottom()-getPaddingBottom());
switch (shape){
case shapeRect:
canvas.drawRect(rect,paint);
break;
case circle:
int r= Math.min(getWidth(),getHeight())/2;
canvas.drawCircle(r+getPaddingLeft(),r+getPaddingTop(),r-getPaddingLeft()-getPaddingRight(),paint);
break;
case round:
canvas.drawRoundRect(rect.left,rect.top,rect.right,rect.bottom,roundRx,roundRy,paint);
break;
}
}
/**
* @param val
* @return
*/
public int dpToPx(int val){
float density = getResources().getDisplayMetrics().density;
return (int) (density * val + 0.5f);
}
}
图二完整代码
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import com.jewelermobile.gangfu.zdydemo1.R;
public class BitmapShaderView extends View {
int radius = 300 ;
public BitmapShaderView(Context context) {
this(context,null);
}
public BitmapShaderView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public BitmapShaderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (radius>0){
setMeasuredDimension(radius*2+getPaddingLeft()+getPaddingRight(),radius*2+getPaddingTop()+getPaddingBottom());
}else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.a0);
/**
* replicate the edge color if the shader draws outside of its
* original bounds
* CLAMP (0), 拉伸
* repeat the shader's image horizontally and vertically
* REPEAT (1),
* repeat the shader's image horizontally and vertically, alternating
* mirror images so that adjacent images always seam
* IRROR (2);
*/
BitmapShader bitmapShader=new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
paint.setShader(bitmapShader);
paint.setColor(Color.RED);
/**
* Blur inside and outside the original border.
NORMAL(0),
* Draw solid inside the border, blur outside.
SOLID(1),
* Draw nothing inside the border, blur outside.
OUTER(2),
* Blur inside the border, draw nothing outside.
INNER(3);
*/
paint.setMaskFilter(new BlurMaskFilter(50,BlurMaskFilter.Blur.SOLID));
canvas.drawCircle(radius+getPaddingLeft(),radius+getPaddingTop(),radius,paint);
}