Android用Canvas画一个真正能跑的跑马灯

以前自学,都是用帧动画来实现跑马灯,这几天常失眠,晚上学东西也学不进,所以用Canvas写个小Demo,这么无聊的应该只有我一个了吧,废话不多说,下面上内容。

老规矩,最后有源码
效果图如下:
在这里插入图片描述

上代码前先介绍下手机坐标系,如下图

在这里插入图片描述
然后是绘制草图,如下:

在这里插入图片描述
大概思路为,开一个耗时线程使彩色背景旋转,来达到跑马灯的效果。

核心:
1.计算出View宽高,矩形宽高,从而算出矩形的坐标点。

1 int canvasWidth = canvas.getWidth(); //画布宽度 2 int canvasHeight = canvas.getHeight(); //画布高度 3 int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形宽高的一半

2.绘制背景,跑马灯,幕布

1 //开始绘制底层背景 2 p.setColor(Color.WHITE); 3 RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 设置个新的长方形,扫描测量 4 canvas.drawRect(oval2,p); 5 //开始绘制跑马灯 6 Paint p1=new Paint(p); 7 Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax, 8 new int[] { 9 10 11 Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW,Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW}, null, Shader.TileMode.REPEAT); 12 p1.setShader(mShader); 13 RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 设置个新的长方形 14 canvas.drawRect(oval,p1); 15 //绘制幕布 16 Paint p2=new Paint(); 17 p2.setColor(Color.BLACK); 18 RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 设置个新的长方形,扫描测量 19 canvas.drawRect(oval3,p2);

3.找到旋转的依靠,并开启一个耗时任务。

1 private Calendar mCalendar; // 时间对象 2 public static final int START_CLOCK = 1000;// 开启时钟的标识 3 Handler mHandler = new Handler() { 4 5 6 7 public void handleMessage(android.os.Message msg) { 8 9 10 11 switch (msg.what) { 12 13 14 15 case DrawView.START_CLOCK: 16 mCalendar = mCalendar.getInstance(); 17 invalidate(); 18 sendEmptyMessageDelayed(DrawView.START_CLOCK, 10); 19 break; 20 case DrawView.STOP_CLOCK: 21 break; 22 default: 23 break; 24 } 25 } 26 };

4.设置彩色正方形旋转

 canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2);

5.将幕布按照彩色正方形反向旋转(不设置则跟着正方形一起旋转);

  canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2);

源码如下:
1.完整java文件

1public class MarqueeView extends View { 2 3 4 5 private Calendar mCalendar; // 时间对象 6 public static final int START_CLOCK = 1000;// 开启时钟的标识 7 Handler mHandler = new Handler() { 8 9 10 11 public void handleMessage(android.os.Message msg) { 12 13 14 15 switch (msg.what) { 16 17 18 19 case DrawView.START_CLOCK: 20 mCalendar = mCalendar.getInstance(); 21 invalidate(); 22 sendEmptyMessageDelayed(DrawView.START_CLOCK, 10); 23 break; 24 case DrawView.STOP_CLOCK: 25 break; 26 default: 27 break; 28 } 29 } 30 }; 31 32 public MarqueeView(Context context) { 33 34 35 36 super(context); 37 } 38 39 public MarqueeView(Context context, @Nullable AttributeSet attrs) { 40 41 42 43 super(context, attrs); 44 mCalendar = mCalendar.getInstance(); 45 if (mCalendar == null) { 46 47 48 49 mCalendar = mCalendar.getInstance(); 50 } 51 mHandler.sendEmptyMessage(START_CLOCK); 52 } 53 54 @Override 55 protected void onDraw(Canvas canvas) { 56 57 58 59 super.onDraw(canvas); 60 drawAxis(canvas); 61 } 62 63 //绘制 64 private void drawAxis(Canvas canvas){ 65 66 67 68 Paint p=new Paint(); 69 int canvasWidth = canvas.getWidth(); //画布宽度 70 int canvasHeight = canvas.getHeight(); //画布高度 71 int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形宽高的一半 72 int sec = mCalendar.get(Calendar.SECOND);//得到当前秒数 73 //开始绘制底层背景 74 p.setColor(Color.WHITE); 75 RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 设置个新的长方形,扫描测量 76 canvas.drawRect(oval2,p); 77 canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2); 78 //开始绘制跑马灯 79 Paint p1=new Paint(p); 80 Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax, 81 new int[] { 82 83 84 Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW,Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW}, null, Shader.TileMode.REPEAT); 85 p1.setShader(mShader); 86 RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 设置个新的长方形,扫描测量 87 canvas.drawRect(oval,p1); 88 //绘制幕布 89 Paint p2=new Paint(); 90 canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2); 91 p2.setColor(Color.BLACK); 92 RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 设置个新的长方形,扫描测量 93 canvas.drawRect(oval3,p2); 94 95 96 } 97} 98

2.xml中调用

1<com................MarqueeView 2 android:layout_width="match_parent" 3 android:layout_height="match_parent"/>

在这里插入图片描述

本文同步分享在 博客“计蒙不吃鱼”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )