Android中利用画图类和线程画出闪烁的心形,送给亲爱的他(她)

简介:

本文讲解主要涉及的知识点:

1.线程控制 
2.画图类 
3.心形函数

大家先看图片:

bluepinkgreenredqingyellow

因为前一段时间在写画图类,刚好有一个线程控制画图闪烁的,我就想说我能不能做一个心形闪烁的,出来的效果就如图,先贴再讲解代码:

里面设置两个类,一个是我们的activity类,这个类用来显示示图,然后建一个继承SurfaceView的类,我们在这里面画图。先贴两个累的代码:

主类名:GameMainActivity,画图类类名:Love.

1   package   com . cz . game . demo; 
2  
3   import   android . app . Activity; 
4   import   android . os . Bundle; 
5  
6   public   class   GameMainActivity   extends   Activity   { 
7        /* *   Called   when   the   activity   is   first   created.   */ 
8  
9        private   Love   love; 
10       @Override 
11       public   void   onCreate(Bundle   savedInstanceState)   { 
12            super . onCreate(savedInstanceState); 
13            this . love   =   new   Love( this ); 
14            setContentView(love); 
15       } 
16  } 
 

画图类:

1    /* * 
2      *   
3      */ 
4    package   com . cz . game . demo; 
5   
6    import   android . content . Context; 
7    import   android . graphics . Canvas; 
8    import   android . graphics . Color; 
9    import   android . graphics . Paint; 
10   import   android . graphics . RectF; 
11   import   android . graphics . Typeface; 
12   import   android . view . SurfaceHolder; 
13   import   android . view . SurfaceView; 
14  
15   /* * 
16     *   @author   CZ 
17     *   
18     */ 
19   public   class   Love   extends   SurfaceView   implements   SurfaceHolder . Callback, 
20             Runnable   { 
21  
22        boolean   mbloop   =   false ; 
23        SurfaceHolder   mSurfaceHolder   =   null ; 
24        private   Canvas   canvas; 
25        int   miCount   =   0 ; 
26        int   y   =   50 ; 
27  
28        /* * 
29          *   @param   context 
30          */ 
31        public   Love(Context   context)   { 
32             super (context); 
33             mSurfaceHolder   =   this . getHolder(); 
34             mSurfaceHolder . addCallback( this ); 
35             this . setFocusable( true ); 
36             this . setKeepScreenOn( true ); 
37             mbloop   =   true ; 
38        } 
39  
40        /* 
41          *   (non-Javadoc) 
42          *   
43          *   @see 
44          *   android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder 
45          *   ,   int,   int,   int) 
46          */ 
47        @Override 
48        public   void   surfaceChanged(SurfaceHolder   holder,   int   format,   int   width, 
49                  int   height)   { 
50             //   TODO   Auto-generated   method   stub 
51  
52        } 
53  
54        /* 
55          *   (non-Javadoc) 
56          *   
57          *   @see 
58          *   android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder 
59          *   ) 
60          */ 
61        @Override 
62        public   void   surfaceCreated(SurfaceHolder   holder)   { 
63             //   TODO   Auto-generated   method   stub 
64             new   Thread( this ) . start(); 
65        } 
66  
67        /* 
68          *   (non-Javadoc) 
69          *   
70          *   @seeandroid.view.SurfaceHolder.Callback#surfaceDestroyed(android.view. 
71          *   SurfaceHolder) 
72          */ 
73        @Override 
74        public   void   surfaceDestroyed(SurfaceHolder   holder)   { 
75             //   TODO   Auto-generated   method   stub 
76             mbloop   =   false ; 
77        } 
78  
79        /* 
80          *   (non-Javadoc) 
81          *   
82          *   @see   java.lang.Runnable#run() 
83          */ 
84        @Override 
85        public   void   run()   { 
86             //   TODO   Auto-generated   method   stub 
87             while   (mbloop)   { 
88                  try   { 
89                       Thread . sleep( 200 ); 
90                  }   catch   (Exception   e)   { 
91                       //   TODO:   handle   exception 
92                  } 
93                  synchronized   (mSurfaceHolder)   { 
94                       Draw(); 
95                  } 
96             } 
97        } 
98  
99        /* * 
100         *   
101         *   Year:2011   Date:2011-7-27   Time:下午06:52:04   Author:CZ   TODO 
102         */ 
103       private   void   Draw()   { 
104            //   TODO   Auto-generated   method   stub 
105            canvas   =   mSurfaceHolder . lockCanvas(); 
106            try   { 
107                 if   (mSurfaceHolder   = =   null   | |   canvas   = =   null )   { 
108                      return ; 
109                 } 
110                 if   (miCount   <   100 )   { 
111                      miCount + + ; 
112                 }   else   { 
113                      miCount   =   0 ; 
114                 } 
115                 Paint   paint   =   new   Paint(); 
116                 paint . setAntiAlias( true ); 
117                 paint . setColor(Color . BLACK); 
118                 canvas . drawRect( 0 ,   0 ,   320 ,   480 ,   paint); 
119                 switch   (miCount   %   6 )   { 
120                 case   0 : 
121                      paint . setColor(Color . BLUE); 
122                      break ; 
123                 case   1 : 
124                      paint . setColor(Color . GREEN); 
125                      break ; 
126                 case   2 : 
127                      paint . setColor(Color . RED); 
128                      break ; 
129                 case   3 : 
130                      paint . setColor(Color . YELLOW); 
131                      break ; 
132                 case   4 : 
133                      paint . setColor(Color . argb( 255 ,   255 ,   181 ,   216 )); 
134                      break ; 
135                 case   5 : 
136                      paint . setColor(Color . argb( 255 ,   0 ,   255 ,   255 )); 
137                      break ; 
138                 default : 
139                      paint . setColor(Color . WHITE); 
140                      break ; 
141                 } 
142                 int   i,   j; 
143                 double   x,   y,   r; 
144 
145                 for   (i   =   0 ;   i   < =   90 ;   i + + )   { 
146                      for   (j   =   0 ;   j   < =   90 ;   j + + )   { 
147                           r   =   Math . PI   /   45   *   i   *   ( 1   -   Math . sin(Math . PI   /   45   *   j)) 
148                                     *   20 ; 
149                           x   =   r   *   Math . cos(Math . PI   /   45   *   j) 
150                                     *   Math . sin(Math . PI   /   45   *   i)   +   320   /   2 ; 
151                           y   =   - r   *   Math . sin(Math . PI   /   45   *   j)   +   400   /   4 ; 
152                           canvas . drawPoint(( float )   x,   ( float )   y,   paint); 
153                      } 
154                 } 
155 
156                 paint . setTextSize( 32 ); 
157                 paint . setTypeface(Typeface . create(Typeface . SERIF,   Typeface . ITALIC)); 
158 
159                 RectF   rect   =   new   RectF( 60 ,   400 ,   260 ,   405 ); 
160                 canvas . drawRoundRect(rect,   ( float )   1 . 0 ,   ( float )   1 . 0 ,   paint); 
161                 canvas . drawText( " Loving   You " ,   75 ,   400 ,   paint); 
162                 mSurfaceHolder . unlockCanvasAndPost(canvas); 
163            }   catch   (Exception   e)   { 
164            } 
165 
166       } 
167 
168  } 
169 
 

关于这个程序要讲解的几点:

1. 画图的时候你可以继承View,也可以继承SurfaceView,这两者的区别在于:surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了SurfaceHolder类,使用getHolder方法获取,还有涉及的surfaceCreated(SurfaceHolder holder),surfaceDestroyed(SurfaceHolder holder),surfaceChanged(SurfaceHolder holder, int format, int width, int height)方法,而在SurfaceHolder.Callback 接口回调中可以通过重写来改变这些方法

2.程序其实很简单, 既然生命了Runnable接口,就有相对应的Run方法,在surfaceCreate()的时候开启线程,线程每隔200ms就刷新一次,这样我们看到的效果就是闪烁的,每200毫秒 画一次图,根据经过的间隔时间来设置画笔的颜色,然后通过循环描点,画出心形,然后设置字体大小,画字和字下面的横线。

3.关于心形函数,是从一个例子中看来得,关于x和y的得到,

x = r * Math.cos(Math.PI / 45 * j)  * Math.sin(Math.PI / 45 * i) + 320 / 2;  y = -r * Math.sin(Math.PI / 45 * j) + 400 / 4;

320是屏幕的宽度,本来竖屏我设置的是480,可是下面得写字,就设置为400的了,关于画更好看的心形还有一个函数,大家可以看下:

5801107438_52486a79a2

有兴趣的童鞋可以设置再做一下.

关于这个代码就这么多,所以就不放附件代码了,把apk放上,之前就打算写这一篇博客,没想到在七夕这天写了。有兴趣的童鞋可以把apk下载下来给女友看哦…



本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/632632,如需转载请自行联系原作者

相关文章
|
4天前
|
API Android开发 iOS开发
深入探索Android与iOS的多线程编程差异
在移动应用开发领域,多线程编程是提高应用性能和响应性的关键。本文将对比分析Android和iOS两大平台在多线程处理上的不同实现机制,探讨它们各自的优势与局限性,并通过实例展示如何在这两个平台上进行有效的多线程编程。通过深入了解这些差异,开发者可以更好地选择适合自己项目需求的技术和策略,从而优化应用的性能和用户体验。
|
17天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2月前
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
Lua的面向对象编程、协同线程与协同函数的概念和使用,以及Lua文件I/O操作的基本方法。
32 4
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
20 3
|
2月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
37 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
31 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
34 1
|
2月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
51 4
|
2月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
26 1
|
24天前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
39 0