Android 自定义Drawable实现跑马灯效果

这个跑马灯效果比自定义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的原理都相差不多,差不多都是旋转画布

相关推荐

  1. Android 定义Drawable实现马灯效果

    2024-07-17 17:38:03       22 阅读
  2. Android 实现马灯效果

    2024-07-17 17:38:03       48 阅读
  3. Python中实现马灯效果

    2024-07-17 17:38:03       40 阅读
  4. css实现马灯(电子屏滚动)效果

    2024-07-17 17:38:03       48 阅读
  5. react mui textfield marquee 马灯效果实现

    2024-07-17 17:38:03       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 17:38:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 17:38:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 17:38:03       58 阅读
  4. Python语言-面向对象

    2024-07-17 17:38:03       69 阅读

热门阅读

  1. Dubbo的RPC协议有哪些独特之处

    2024-07-17 17:38:03       19 阅读
  2. vue中缩放比的使用

    2024-07-17 17:38:03       20 阅读
  3. Linux指令&&ros学习&&python深度学习&&bug学习笔记

    2024-07-17 17:38:03       18 阅读
  4. 中文科技核心论文发表

    2024-07-17 17:38:03       19 阅读
  5. MPS 后端

    2024-07-17 17:38:03       23 阅读
  6. C# ForgettableKnowledge

    2024-07-17 17:38:03       19 阅读
  7. HarmonyOS 如何下载网络图片

    2024-07-17 17:38:03       22 阅读
  8. Postman 接口测试详解

    2024-07-17 17:38:03       18 阅读