package com.example.cloud; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import java.util.ArrayList; import java.util.List; public class SpreadView extends View { private Paint centerPaint; //中心圆paint private Paint paint; //图片白框 private int radius = 100; //中心圆半径 private Paint spreadPaint; //扩散圆paint private float centerX;//圆心x private float centerY;//圆心y private int distance = 1; //每次圆递增间距 private int maxRadius = 80; //最大圆半径 private int delayMilliseconds = 30;//扩散延迟间隔,越大扩散越慢 private List<Integer> spreadRadius = new ArrayList<>();//扩散圆层级数,元素为扩散的距离 private List<Integer> alphas = new ArrayList<>();//对应每层圆的透明度 public SpreadView(Context context) { this(context, null, 0); } public SpreadView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public SpreadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpreadView, defStyleAttr, 0); radius = a.getInt(R.styleable.SpreadView_spread_radius, radius); maxRadius = a.getInt(R.styleable.SpreadView_spread_max_radius, maxRadius); //中心园的颜色 int centerColor = a.getColor(R.styleable.SpreadView_spread_center_color, ContextCompat.getColor(context, R.color.a_195092)); //渐变的颜色 int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.a_496696)); distance = a.getInt(R.styleable.SpreadView_spread_distance, distance); a.recycle(); centerPaint = new Paint(); centerPaint.setColor(centerColor); centerPaint.setAntiAlias(true); //最开始不透明且扩散距离为0 alphas.add(255); spreadRadius.add(0); spreadPaint = new Paint(); spreadPaint.setAntiAlias(true); spreadPaint.setAlpha(255); spreadPaint.setColor(spreadColor); //白色边框 paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); paint.setColor(Color.WHITE); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //圆心位置 centerX = w / 2; centerY = h / 2; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < spreadRadius.size(); i++) { int alpha = alphas.get(i); spreadPaint.setAlpha(alpha); int width = spreadRadius.get(i); //绘制扩散的圆 canvas.drawCircle(centerX, centerY, radius + width, spreadPaint); //每次扩散圆半径递增,圆透明度递减 if (alpha > 0 && width < 300) { alpha = alpha - distance > 0 ? alpha - distance : 1; alphas.set(i, alpha); spreadRadius.set(i, width + distance); } } //当最外层扩散圆半径达到最大半径时添加新扩散圆 if (spreadRadius.get(spreadRadius.size() - 1) > maxRadius) { spreadRadius.add(0); alphas.add(255); } //超过8个扩散圆,删除最先绘制的圆,即最外层的圆 if (spreadRadius.size() >= 8) { alphas.remove(0); spreadRadius.remove(0); } //中间的圆 // canvas.drawCircle(centerX, centerY, radius, centerPaint); // 获取资源流 Resources rec = getResources(); BitmapDrawable bitmapDrawable = (BitmapDrawable) rec.getDrawable(R.drawable.img); Bitmap bitmap = bitmapDrawable.getBitmap(); // canvas.drawBitmap(bitmap,centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2),centerPaint); //TODO 可以在中间圆绘制文字或者图片 //获得图片的宽度 int width=bitmap.getWidth(); //获得图片的高度 int height=bitmap.getHeight(); //短的二分之一作为半径 int radius=height>width?width/2:height/2; //重新定义的一个画布,这一步很关键 Paint mPaint = new Paint(); //抗锯齿 mPaint.setAntiAlias(true); // Bitmap bitmap1 = Bitmap.createBitmap(width,height, // Bitmap.Config.ARGB_8888); // Canvas bitmapCanvas = new Canvas(bitmap1); // super.onDraw(bitmapCanvas); //圆形的框 Bitmap cB = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas cCanv = new Canvas(cB); //在控件中间画一个 cCanv.drawCircle(width/ 2, height/ 2, radius, mPaint); canvas.drawBitmap(bitmap, centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2), mPaint); //dst是后画的图形 mPaint.setXfermode(new PorterDuffXfermode( PorterDuff.Mode.DST_IN)); //一定要用之前的画布,不然会出现边角是黑色 cCanv.drawBitmap(cB, centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2), mPaint); //给图形加边框 canvas.drawCircle(centerX, centerY, radius, paint); //延迟更新,达到扩散视觉差效果 postInvalidateDelayed(delayMilliseconds); } }
<declare-styleable name="SpreadView"> <!--中心圆颜色--> <attr name="spread_center_color" format="color" /> <!--中心圆半径--> <attr name="spread_radius" format="integer" /> <!--扩散圆颜色--> <attr name="spread_spread_color" format="color" /> <!--扩散间距--> <attr name="spread_distance" format="integer" /> <!--扩散最大半径--> <attr name="spread_max_radius" format="integer" /> <!--扩散延迟间隔--> <attr name="spread_delay_milliseconds" format="integer" /> </declare-styleable>