漫画小新 發表於 2025-11-29 14:14:32

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

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>前言</li><li>效果图如下:</li><li>核心:</li><li>总结&nbsp;</li></ul></div><p class="maodian"></p><h2>前言</h2>
<p>以前自学,都是用帧动画来实现跑马灯,这几天常失眠,晚上学东西也学不进,所以用Canvas写个小Demo,这么无聊的应该只有我一个了吧,废话不多说,下面上内容。</p>
<p>老规矩,最后有源码</p>
<p class="maodian"></p><h2>效果图如下:</h2>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/20251129141536805.gif" /></p>
<p><strong>上代码前先介绍下手机坐标系,如下图</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/20251129141536806.jpg" /></p>
<p><strong>然后是绘制草图,如下:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/20251129141536807.jpg" /></p>
<p><strong>大概思路为,开一个耗时线程使彩色背景旋转,来达到跑马灯的效果。</strong></p>
<p class="maodian"></p><h2>核心:</h2>
<p><strong>1.计算出View宽高,矩形宽高,从而算出矩形的坐标点。</strong></p>
<div class="jb51code"><pre class="brush:java;">int canvasWidth = canvas.getWidth();       //画布宽度
      int canvasHeight = canvas.getHeight();   //画布高度
      int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形宽高的一半</pre></div>
<p><strong>2.绘制背景,跑马灯,幕布</strong></p>
<div class="jb51code"><pre class="brush:java;">//开始绘制底层背景
      p.setColor(Color.WHITE);
      RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 设置个新的长方形,扫描测量
      canvas.drawRect(oval2,p);
      //开始绘制跑马灯
      Paint p1=new Paint(p);
      Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax,
                new int[] { 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);
      p1.setShader(mShader);
      RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 设置个新的长方形
      canvas.drawRect(oval,p1);
      //绘制幕布
      Paint p2=new Paint();
      p2.setColor(Color.BLACK);
      RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 设置个新的长方形,扫描测量
      canvas.drawRect(oval3,p2);</pre></div>
<p><strong>3.找到旋转的依靠,并开启一个耗时任务。</strong></p>
<div class="jb51code"><pre class="brush:java;">private Calendar mCalendar; // 时间对象
    public static final int START_CLOCK = 1000;// 开启时钟的标识
    Handler mHandler = new Handler() {
      public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case DrawView.START_CLOCK:
                  mCalendar = mCalendar.getInstance();
                  invalidate();
                  sendEmptyMessageDelayed(DrawView.START_CLOCK, 10);
                  break;
                case DrawView.STOP_CLOCK:
                  break;
                default:
                  break;
            }
      }
    };</pre></div>
<p><strong>4.设置彩色正方形旋转</strong></p>
<div class="jb51code"><pre class="brush:java;">canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2);</pre></div>
<p><strong>5.将幕布按照彩色正方形反向旋转(不设置则跟着正方形一起旋转);</strong></p>
<div class="jb51code"><pre class="brush:java;">canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2);</pre></div>
<p><strong>源码如下:</strong><strong>1.完整java文件</strong></p>
<div class="jb51code"><pre class="brush:java;">public class MarqueeView extends View {
    private Calendar mCalendar; // 时间对象
    public static final int START_CLOCK = 1000;// 开启时钟的标识
    Handler mHandler = new Handler() {
      public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case DrawView.START_CLOCK:
                  mCalendar = mCalendar.getInstance();
                  invalidate();
                  sendEmptyMessageDelayed(DrawView.START_CLOCK, 10);
                  break;
                case DrawView.STOP_CLOCK:
                  break;
                default:
                  break;
            }
      }
    };

    public MarqueeView(Context context) {
      super(context);
    }

    public MarqueeView(Context context, @Nullable AttributeSet attrs) {
      super(context, attrs);
      mCalendar = mCalendar.getInstance();
      if (mCalendar == null) {
            mCalendar = mCalendar.getInstance();
      }
      mHandler.sendEmptyMessage(START_CLOCK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      drawAxis(canvas);
    }

    //绘制
    private void drawAxis(Canvas canvas){
      Paint p=new Paint();
      int canvasWidth = canvas.getWidth();       //画布宽度
      int canvasHeight = canvas.getHeight();   //画布高度
      int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形宽高的一半
      int sec = mCalendar.get(Calendar.SECOND);//得到当前秒数
      //开始绘制底层背景
      p.setColor(Color.WHITE);
      RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 设置个新的长方形,扫描测量
      canvas.drawRect(oval2,p);
      canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2);
      //开始绘制跑马灯
      Paint p1=new Paint(p);
      Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax,
                new int[] { 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);
      p1.setShader(mShader);
      RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 设置个新的长方形,扫描测量
      canvas.drawRect(oval,p1);
      //绘制幕布
      Paint p2=new Paint();
      canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2);
      p2.setColor(Color.BLACK);
      RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 设置个新的长方形,扫描测量
      canvas.drawRect(oval3,p2);


    }
}</pre></div>
<p><strong>2.xml中调用</strong></p>
<div class="jb51code"><pre class="brush:xml;">&lt;com................MarqueeView
    android:layout_width="match_parent"
    android:layout_height="match_parent"/&gt;</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/20251129141536808.jpg" /></p>
<p class="maodian"></p><h2>总结&nbsp;</h2>
<p>到此这篇关于Android如何用Canvas画一个真正能跑的跑马灯的文章就介绍到这了,更多相关Android用Canvas画跑马灯内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Android 中TextView中跑马灯效果的实现方法</li><li>Android TextView实现跑马灯效果的方法</li><li>Android实现跑马灯效果的方法</li><li>Android实现跑马灯效果的两种简单方式</li><li>Android实现跑马灯效果的代码详解</li><li>android自定义View实现跑马灯效果</li><li>Android实现垂直跑马灯效果</li><li>android使用TextView实现跑马灯效果</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Android如何用Canvas画一个真正能跑的跑马灯