带阴影的圆形 — CircleShadow
避坑:关闭硬件加速,否则没有阴影的效果
package com.baina.mydemo.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.baina.mydemo.R;
import androidx.annotation.Nullable;
/**
* @ClassName CircleShadow
* @Description 带阴影的圆形
* 阴影半径 + 中心圆半径 = view的最小边长度
* 需要关闭硬件加速,否阴影显示不出来
* @Author {Bai Jiansong}
* @Date 2022/4/30 20:20
* @Version 1.0
*/
public class CircleShadow extends View {
private static final String TAG = "JPush";
private float shadowRadius = 10;
private Context context;
private Paint paint = new Paint();
public CircleShadow(Context context) {
this(context, null);
}
public CircleShadow(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleShadow(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
initView(attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 取最小值
float radius = Math.min(getWidth() / 2f, getHeight() / 2f) - shadowRadius;
if (radius < 0) {
radius = 0;
}
canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, radius, paint);
}
private void initView(AttributeSet attrs) {
if (context == null || attrs == null) {
Log.i(TAG, "initView: context or attrs is null");
return;
}
TypedArray attr = getTypedArray(context, attrs, R.styleable.CircleShadow);
int shadowColor = 0;
int circleColor = 0;
try {
shadowColor = attr.getColor(R.styleable.CircleShadow_cs_shadowColor, Color.BLACK);
circleColor = attr.getColor(R.styleable.CircleShadow_cs_circleColor, Color.WHITE);
shadowRadius = attr.getDimension(R.styleable.CircleShadow_cs_shadowRadius, 0);
} finally {
attr.recycle();
}
paint.setColor(circleColor);
// 设定阴影(柔边距离,X 轴位移,Y 轴位移,阴影颜色)
paint.setShadowLayer(shadowRadius, 0, 0, shadowColor);
}
private TypedArray getTypedArray(Context context, AttributeSet attributeSet, int[] attr) {
return context.obtainStyledAttributes(attributeSet, attr, 0, 0);
}
}
package com.baina.mydemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class CircleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circle);
}
}
AndroidManifest.xml 里关闭硬件加速:
<activity android:name=".CircleActivity"
android:hardwareAccelerated="false"/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#03A9F4"
tools:context=".CircleActivity">
<com.baina.mydemo.view.CircleShadow
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
app:cs_circleColor="#ffffff"
app:cs_shadowColor="#252020"
app:cs_shadowRadius="15dp"/>
</RelativeLayout>
value目录下,增加 attrs.xml资源:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleShadow">
<attr name="cs_shadowRadius" format="dimension"/>
<attr name="cs_shadowColor" format="color"/>
<attr name="cs_circleColor" format="color"/>
</declare-styleable>
</resources>