热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android利用SurfaceView实现简单计时器

这篇文章主要为大家详细介绍了Android利用SurfaceView实现一个简单计时器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

自学了android有几个月了,跟着网上的节奏,应该早点写些博客来提高自己的水准的。但苦于技术水准始终不自信(也是不过关的结果吧),就一直只是将自己学习过程中的问题和重要的知识点写在自己的笔记文档中。

但,总感觉一个人写下来成就感还是欠缺了那么一些,而且有些问题及解答方法抛出来,是有可能得到更多好的反馈及解决方案的。于是,本着不作不会死的心态,一步一步在技术成长的道路前行——>这篇博客就是其中一步!

若博客中有些技术知识点有误或者有更优化的解答方案,还望各位小伙伴多多指出。

以下是正题了:

目标:利用SurfaceView实现一个简单的计时器

图示:

描述:1.利用SurfaceView来实现计时功能,同时不断将圆弧画满;2.点击按钮可以停止计时;

重点:

1.自定义SurfaceView中针对SurfaceHolder.CallBack的三个方法进行覆写;

2.通过surfaceHolder.lockCanvas()在新开的线程中得到canvas对象,从而进行图形和时间文字的绘制;

3.通过设置flag值,从而控制在线程run()方法中逻辑代码的执行;

重要部分代码:

public TestView(Context context) { 
  super(context); 
  surfaceHolder = getHolder(); 
  surfaceHolder.addCallback(this); 
  countThread = new CountThread(surfaceHolder); 
} 
 
public TestView(Context context, AttributeSet attributeSet) { 
  super(context, attributeSet); 
  surfaceHolder = getHolder(); 
  surfaceHolder.addCallback(this); 
  countThread = new CountThread(surfaceHolder); 
} 

以上为自定义的SurfaceView(TestView)的构造函数,做相应的初始化工作。(第二个构造方法在实现过程中没有覆写,导致如果是通过布局文件引入进Activity中时,则显示不出View——>也就是一般自定义View一定要覆写的构造方法)。
在构造方法中初始化了自定义的内部线程类CountThread,用来执行绘制工作。

以下为CountThread类的run()方法执行逻辑:

@Override 
    public void run() { 
      Canvas canvas = null; 
      int pivotX = getResources().getDisplayMetrics().widthPixels / 2; 
      RectF rectF = new RectF(pivotX - 300, pivotX - 300, pivotX + 300, pivotX + 300); 
      while (!isStop) { 
        try { 
          canvas = surfaceHolder.lockCanvas(); 
          canvas.drawColor(Color.WHITE);//设置画布背景为白色 
//          canvas.drawRoundRect(300, 300, 600, 600, 150, 150, paint);//直接使用该行代码来画圆是行不通的,因为这个方法要求版本21,我的手机运行android版本是19 
          canvas.drawArc(rectF, -90, endAngle++, false, paint);//-90在这里不等于270,所以要想从最上方开始画弧,就得用-90 
          canvas.drawText(countTime(endAngle), pivotX, pivotX, paintText);//显示计算的时间 
          Thread.sleep(1000); 
        } catch (Exception e) { 
          e.printStackTrace(); 
        } finally { 
          if (canvas != null) {//需要对canvas进行非空判断 
            surfaceHolder.unlockCanvasAndPost(canvas); 
          } 
        } 
      } 
    } 

主要就是通过Thread.sleep(1000)来停顿一秒,从而通过endAngle来计数。

至此,基本的程序逻辑已经实现。再讲该自定义View引入进Activity指定的layout布局文件中即可进行显示。

但,这其中也会涉及到相应的问题。譬如:

1.图示中的按钮无法显示出来,只能看到自定义的SurfaceView的视图;

我的做法是:将布局设定为FrameLayout即可。因为SurfaceView是浮在窗口的一层,那么就可以把它看做一个图层。

2.java.lang.IllegalThreadStateException:Thread already started

该错误表明,线程已经存在了。这种错误的操作重现是:按下home键或者menu键会导致该自定的SurfaceView销毁,但线程并没有被销毁,再次启动该自定义SurfaceView的时候又去重新启动该线程。解决的方法是:

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
  if (!countThread.isAlive()) {//如果线程不存在,则启动线程——>当应用挂起的时候Thread是存在的,如果不做这个判断,会报“Thread already started ”错误 
    countThread.start();//SurfaceView创建时开启线程 
  } 
} 

在surfaceCreated()方法中对该线程是否是在存活中进行判断。

当然,这里面还有最重要的一个问题:

当按下home键或者menu键时,程序是没有在计时的。那么这种情况下,我的一个解决方案是,通过开启一个service来接收程序停止( onStop() )时已经计时的数值,然后传递给service记下并计时,当应用程序界面重新回归屏幕时( onRestart() )则将数据取出并回传到自定义的SurfaceView的逻辑run()方法中继续计时。

整个小程序的代码可以通过以下链接下载:

点击进入下载页面:http://xiazai.jb51.net/201701/yuanma/AndroidSurfaceView(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 程序员如何优雅应对35岁职业转型?这里有深度解析
    本文探讨了程序员在职业生涯中如何通过不断学习和技能提升,优雅地应对35岁左右的职业转型挑战。我们将深入分析当前热门技术趋势,并提供实用的学习路径。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 本文将深入探讨PHP编程语言的基本概念,并解释PHP概念股的含义。通过详细解析,帮助读者理解PHP在Web开发和股票市场中的重要性。 ... [详细]
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • JavaScript 中创建对象的多种方法
    本文详细介绍了 JavaScript 中创建对象的几种常见方式,包括对象字面量、构造函数和 Object.create 方法,并提供了示例代码和属性描述符的解释。 ... [详细]
  • 2020初级电工模拟题库与实操视频指南
    本文提供2020年初级电工模拟考试题库及实操视频资源,涵盖最新大纲和真题解析,帮助考生高效备考。内容包括理论知识、实操技能以及详细答案解析,适用于全国各地区电工(初级)考试。 ... [详细]
  • 本教程将详细介绍Python中的包、模块、类和函数的概念,探讨它们在程序中的作用及相互关系,帮助读者更好地理解Python的结构化编程。 ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
  • 国庆头像生成小程序体验
    介绍一个可以快速生成带有国旗元素的国庆头像的小程序,带您回顾这一流行趋势。 ... [详细]
  • 微信小程序:授权登录与手机号绑定
    本文详细介绍了微信小程序中用户授权登录及绑定手机号的流程,结合官方指引和实际开发经验,提供了一套完整的实现方案,帮助开发者更好地理解和应用。 ... [详细]
  • 在使用Netty 4.1.48版本运行自带的HTTP服务器示例时,观察到大量本地IP环回连接。本文将探讨这些环回连接的原因,并解释其与TCP连接的关系。 ... [详细]
  • 使用JS、HTML5和C3创建自定义弹出窗口
    本文介绍如何结合JavaScript、HTML5和C3.js来实现一个功能丰富的自定义弹出窗口。通过具体的代码示例,详细讲解了实现过程中的关键步骤和技术要点。 ... [详细]
  • 在项目中使用 Redis 时,了解其不同架构模式(如单节点、主从复制、哨兵模式和集群)对于确保系统的高可用性和扩展性至关重要。本文将详细探讨这些模式的特点和应用场景。 ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • 本文深入探讨了小程序中父组件与子组件之间的数据传递方式,特别是通过事件触发和属性绑定实现的值传递机制。文中详细介绍了如何从子组件向父组件传递数据,并进一步由父组件传递给其他子组件。 ... [详细]
author-avatar
拍友2602921297
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有