一、首先展示下效果
二、如何使用自定义Drawable
private void initRainbowView(){
TextView rainbowView = findViewById(R.id.rainbowDrawableView);
RainbowDrawable.Builder builder = new RainbowDrawable.Builder();
//设置Drawable的背景色,也可以不设置。
builder.setBackgroundColor(Color.parseColor("#60000000"));
//设置彩虹边框旋转一周需要的时间。
builder.setDuration(2000);
//设置圆角
builder.setRadius(50);
//设置彩虹条宽度
builder.setStrokeWidth(10);
//设置彩虹条的颜色变化
builder.setGradientColorAndPosition(new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.GREEN, Color.RED},new float[]{0f,0.2f,0.4f,0.6f,0.8f,1.0f});
rainbowView.setBackgroundDrawable(builder.build());
}
三、如何实现彩虹条边框
public void draw(@NonNull Canvas canvas) {
Rect rect = getBounds();
//画背景图
if (bgColor != 0) {
bgPaint.setColor(bgColor);
bgPaint.setStrokeWidth(strokeWidth);
canvas.drawPath(bgPath, bgPaint);
canvas.saveLayer(drawableRect, paintLayer, ALL_SAVE_FLAG);
}
canvas.rotate(degree, rect.width() / 2, rect.height() / 2);
//画彩色圆盘
canvas.drawCircle(rect.width() / 2, rect.height() / 2, rect.width(), paintGradient);
canvas.rotate(-degree, rect.width() / 2, rect.height() / 2);
{
rainbowPaint.setStrokeWidth(strokeWidth);
//画边框并且应用遮罩效果
canvas.saveLayer(drawableRect, paintMask, ALL_SAVE_FLAG);
canvas.drawPath(rainbowPath, rainbowPaint);
canvas.restore();
}
if (bgColor != 0) {
canvas.restore();
}
//启动动画
if (requestPlay) {
requestPlay = false;
scheduleSelf(this, SystemClock.uptimeMillis() + timeStep);
}
}
四、技术要点
1.应用遮罩效果(注意:部分效果不支持硬件加速,需要关闭硬件加速功能。遮罩效果需要使用到saveLayer方法,这个方法影响描画性能)
paintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
2.彩虹条是流动的,所以应用到的自定义Drawable动画的实现。
scheduleSelf(this, SystemClock.uptimeMillis() + timeStep);
unscheduleSelf(this);
五、git地址
https://github.com/mjlong123123/ExampleProject/tree/dev