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

news/2024/7/8 1:21:08 标签: android, java, 开发语言
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


http://www.niftyadmin.cn/n/5535841.html

相关文章

【HALCON】如何实现hw窗口自适应相机拍照成像的大小

前言 在开发一个喷码检测软件的时候碰到相机成像和hw窗体的大小不一致,hw太小显示不完全成像的图片,这使得成像不均匀,现场辨别起来比较不直观,因此需要对其进行一个调整。 解决 省略掉读取图片的环节,我们只需要将…

【C#】函数方法、属性分文件编写

1.思想 分文件编写是面向对象编程的重要思想,没有实际项目作为支撑很难理解该思想的精髓,换言之,一两个函数代码量因为太少无法体现分文件编写减少大量重复代码的优势。 2.项目结构介绍 整项目的名称叫AutoMetadata,是一个基于W…

git使用遇到的问题记录

文章目录 1. 记录以下问题*error: RPC failed; HTTP 307 curl 22 The requested URL returned error: 307* 1. 记录以下问题 error: RPC failed; HTTP 307 curl 22 The requested URL returned error: 307 第一种:clone的仓库地址或者账户密码发生改变;…

oracle如何判定数据库的时区并进行时间的时区转换

在Oracle数据库中,判断和设置时区以及进行时区的转换是很重要的功能。以下是一些基本的步骤和方法: 1. 判定数据库的时区 要查看Oracle数据库的时区,你可以查询DBTIMEZONE。例如: sql SELECT DBTIMEZONE FROM DUAL; 这将返回…

【操作系统期末速成】 EP01 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言🚀🚀🚀二、正文:☀️☀️☀️1.1 考点一:操作系统的概率及特征 三、总结:🍓🍓🍓 一、前言🚀🚀🚀 ☀️ 回报不在行动…

ios CCNSDate.m

// // CCNSDate.h // CCFC // // Created by xichen on 11-12-17. // Copyright 2011年 ccteam. All rights reserved. //#import <Foundation/Foundation.h>interface NSDate(cc)// 获取系统时间(yyyy-MM-dd HH:mm:ss.SSS格式)(NSString *)getSystemTimeStr;// prin…

Kotlin中的关键字

Kotlin 中的关键字可分为几个大类&#xff1a; 声明/定义关键字&#xff1a; class&#xff1a;用于定义类interface&#xff1a;用于定义接口object&#xff1a;用于声明对象&#xff0c;Kotlin中实现单例模式的关键字fun&#xff1a;用于声明函数var&#xff1a;用于声明可变…

没有使用Redis相关的代码或依赖,但在 `application.yaml` 配置文件中配置了Redis参数,项目启动时是否会报错

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…