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的原理都相差不多,差不多都是旋转画布

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_zxw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值