这个跑马灯效果比自定义VIew实现丝滑,丝滑效果主要还是对颜色的取值比较关键
public class FluidColorfulFrameDrawable extends Drawable { private Paint paint; private RectF bounds; private RectF rectF = new RectF(); private float defaultRadius = SizeUtils.dp2px(10); private float defaultStrokeWidth = SizeUtils.dp2px(10); private int colorPurple = Color.parseColor("#855bff"); private int colorBlue = Color.parseColor("#3cfff8"); private int colorGreen = Color.parseColor("#855bff"); private int colorYellow = Color.parseColor("#ffd220"); private int[] colors = {colorPurple,colorBlue, colorGreen, colorYellow,colorPurple,colorBlue, colorGreen, colorYellow, colorPurple,colorBlue, colorGreen}; private int strokeWidth; private Matrix mtx = new Matrix(); private float degree = 0f; public FluidColorfulFrameDrawable(int strokeWidth) { this.strokeWidth = strokeWidth; init(); } // Getter和Setter方法 public float getDegree() { return degree; } public void setDegree(float value) { degree = value; invalidateSelf(); } private void init(){ paint = new Paint(); paint.setStyle(Paint.Style.STROKE); if(strokeWidth<0){ paint.setStrokeWidth(defaultStrokeWidth); }else { paint.setStrokeWidth(strokeWidth); } } @Override public void draw(@NonNull Canvas canvas) { mtx.reset(); mtx.setRotate(degree, bounds.centerX(), bounds.centerY()); ((SweepGradient)paint.getShader()).setLocalMatrix(mtx); // canvas.drawRoundRect(rectF, defaultRadius, defaultRadius, paint); canvas.drawRect(rectF,paint); } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); bounds = new RectF(left, top, right, bottom); rectF.left = 0;//defaultStrokeWidth / 2 rectF.top = 0;//defaultStrokeWidth / 2 // rectF.right = bounds.width() - defaultStrokeWidth / 2; rectF.right = bounds.width(); // rectF.bottom = bounds.height() - defaultStrokeWidth / 2; rectF.bottom = bounds.height(); SweepGradient gradient = new SweepGradient(bounds.centerX(), bounds.centerY(), colors, null); paint.setShader(gradient); } @Override public void setAlpha(int alpha) { paint.setAlpha(alpha); } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { paint.setColorFilter(colorFilter); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } // 创建一个Property对象用于ObjectAnimator与"degree"属性交互 private Property<FluidColorfulFrameDrawable, Float> degreeProperty = new Property<FluidColorfulFrameDrawable, Float>(Float.class, "degree") { @Override public Float get(FluidColorfulFrameDrawable object) { // 返回当前degree的值 return object.getDegree(); // 假设有一个getDegreeValue()方法来获取当前值 } @Override public void set(FluidColorfulFrameDrawable object, Float value) { // 设置degree的值并触发任何必要的更新 object.setDegree(value); } }; private ObjectAnimator fluidAnim; public void startFluid() { fluidAnim = ObjectAnimator.ofFloat(this, degreeProperty, 0f, 360f); fluidAnim.setDuration(10000L); fluidAnim.setInterpolator(new LinearInterpolator()); fluidAnim.setRepeatCount(ValueAnimator.INFINITE); fluidAnim.start(); } public void cancelFluid() { fluidAnim.cancel(); } }
使用:
private void setBackGroundDrawable(RelativeLayout layout){ FluidColorfulFrameDrawable fluidColorfulFrameDrawable = new FluidColorfulFrameDrawable(paddingWidth); fluidColorfulFrameDrawable.setBounds(0,0,ScreenUtils.getScreenWidth(), ScreenUtils.getScreenHeight()-getHeight(context)); layout.setBackground(fluidColorfulFrameDrawable); fluidColorfulFrameDrawable.startFluid(); }
把最外层的布局layout传进来就行
paddingWidth是边距也就是灯带的宽度,这个自己定义就行
ScreenUtils.getScreenWidth(),ScreenUtils.getScreenHeight()都是三方工具
implementation 'com.blankj:utilcodex:1.30.6'
getHeight是获取状态栏高度
public static int getHeight(Context context) { int statusBarHeight = 0; int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = context.getResources().getDimensionPixelSize(resourceId); } if (isFlymeOs4x()) { return 2 * statusBarHeight; } return statusBarHeight; }
这里可以根据自己需要到底去不去掉这个状态栏高度
其实跟自定义View的原理都相差不多,差不多都是旋转画布