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

复制代码
public class MyMarqueeView extends View {

    private Paint paint;
    private RectF rect;
    private float startX, startY, endX, endY;
    private float currentX,currentY;
    /**
     * 灯大小
     */
    private int radius = 15;
    /**
     * 多少毫秒绘制一个圆点
     * 最小80
     */
    private int time = 100;
    /**
     * 绘制的圆点个数,如果数量等于全部数量重新绘制或者取消
     */
    int drawNumber = 1;
    private int[] myColors = new int[]{Color.YELLOW,Color.BLUE,Color.RED,Color.GREEN};
    private String colorPurple = "#8000FF";
    private String colorOrange = "#FFA500";
    private String colorPink = "#FFC0CB";
    private String colorGolden = "#D4AF37";
    public MyMarqueeView(Context context) {
        super(context);
        init();
    }

    public MyMarqueeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyMarqueeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 一行多少个点点
     * 一列有多少个点点
     */
    private int hNumber,vNumber;
    /**
     *  单行某个颜色有多少个
     *  单列某个颜色有多少个
     */
    private int hChildNumber,vChildNumber;
    int width,height;
    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        width = ScreenUtils.getScreenWidth();
        height = ScreenUtils.getScreenHeight()-getStatusBarHeight()-radius;
        //获取一行一列有多少个点点
        hNumber = width/(2*radius)-1;
        hChildNumber = hNumber/myColors.length;
        vNumber = height/(2*radius)-1;
        vChildNumber = vNumber/myColors.length;

        rect = new RectF(0, 0, width, height);
        startX = rect.left+ radius;
        startY = rect.top + radius;
        endX = rect.right - radius;
        endY = rect.bottom - 2*radius;
        currentX = startX;
        currentY = startY;
        startTimer();
    }

   private void startTimer(){

       CountDownTimer timer = new CountDownTimer(4*time,time) {
           @Override
           public void onTick(long millisUntilFinished) {
               switch (drawNumber){
                   case 1:
                       color = YELLOW;
                       break;
                   case 2:
                       color = BLUE;
                       break;
                   case 3:
                       color = RED;
                       break;
                   case 4:
                       color = GREEN;
                       break;
               }
               drawNumber++;
               invalidate();
           }

           @Override
           public void onFinish() {
               drawNumber = 1;
               this.start();
           }
       };
       timer.start();
   }

    /**
     * 四种颜色
     */
   private String color = "";
   private static final String YELLOW = "yellow",BLUE = "blue",RED = "red",GREEN = "green";

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setStrokeWidth(20);
        // 绘制跑马灯效果
        switch (color){
            case YELLOW:
                LinearGradient gradient = new LinearGradient(0,0,width,height,Color.parseColor(colorPurple),
                        Color.parseColor(colorPink), Shader.TileMode.CLAMP);
                paint.setShader(gradient);
                drawYellowCircle(canvas,0,0);
                break;
            case BLUE:
                LinearGradient gradient1 = new LinearGradient(0,0,width,height,Color.GREEN,
                        Color.YELLOW, Shader.TileMode.CLAMP);
                paint.setShader(gradient1);
                drawYellowCircle(canvas,hChildNumber,vChildNumber);
                break;
            case RED:
                LinearGradient gradient2 = new LinearGradient(0,0,width,height,Color.RED,
                        Color.parseColor(colorOrange), Shader.TileMode.CLAMP);
                paint.setShader(gradient2);
                drawYellowCircle(canvas,2*hChildNumber,2*vChildNumber);
                break;
            case GREEN:
                LinearGradient gradient3 = new LinearGradient(0,0,width,height,Color.parseColor(colorPurple),
                        Color.parseColor(colorGolden), Shader.TileMode.CLAMP);
                paint.setShader(gradient3);
                drawYellowCircle(canvas,3*hChildNumber,3*vChildNumber);
                break;
        }

    }

    private void drawYellowCircle(Canvas canvas,int hStartNumebr,int vStartNumebr){
        //画上边点点
        currentX = startX + hStartNumebr*2*radius;
        currentY = startY;
        canvas.drawLine(currentX,startY,currentX+hChildNumber*2 * radius,startY,paint);

        //画右边
        currentY = startY+vStartNumebr*2*radius;
        canvas.drawLine(endX,currentY,endX,currentY+vChildNumber*2*radius,paint);

        //画底部点点
        currentX = endX-hStartNumebr*2*radius;
        canvas.drawLine(currentX,endY,currentX-hChildNumber*2*radius,endY,paint);

        //画左边
        currentY = endY-vStartNumebr*2*radius;
        canvas.drawLine(startX,currentY,startX,currentY-vChildNumber*2*radius,paint);
    }


}

这里用LinearGradient加的渐变色

也可以直接paint.setColor设置颜色,time的大小控制画的速度也就是灯的速度,建议100毫秒

使用的话直接布局用就就可以

另一种方案是画圆点,就是换换方法的事,drawLine换drawCircle

相关推荐
better_liang1 小时前
每日Java面试场景题知识点之-消息队列MQ核心场景与实战
java·面试·kafka·消息队列·rabbitmq·rocketmq·mq
小江的记录本1 小时前
【JVM虚拟机】垃圾回收GC:四种引用类型:强引用、软引用、弱引用、虚引用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试
小马爱打代码2 小时前
Spring源码 第四篇:Spring 5 源码深度拆解:AOP 全流程核心原理
java·后端·spring
巴博尔2 小时前
UNIAPP中NVUE页面 动画
android·前端·javascript·ios·uni-app
deepin_sir2 小时前
10 - 函数
开发语言·python
better_liang2 小时前
每日Java面试场景题知识点之-SpringBoot启动流程
java·面试·springboot·源码解析·启动流程
RyFit2 小时前
Java + AI 实战:Spring AI 从入门到企业级落地
java·人工智能·spring
z落落2 小时前
C#String字符串
开发语言·c#·php
猫头虎-前端技术2 小时前
JS 作用域与闭包:从变量提升到闭包陷阱的超详细解析
开发语言·javascript·云计算·bootstrap·ecmascript·openstack·perl
枫叶林FYL3 小时前
项目十:事件溯源仓储管理系统(WMS)仿真实现
开发语言·python