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

发布于:2024-07-01 ⋅ 阅读:(12) ⋅ 点赞:(0)
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