链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378328.html
一、概述
这次要做一个简单的涂鸦板应用,以前在Qt上实现过,突然想到要把它在Android上实现,呵呵,既简单又有趣。
二、实现
新建工程MyWall,修改/res/layout/main.xml文件,在里面添加一个SurfaceView和两个Button,用到了RelativeLayout布局,完整的main.xml文件如下:
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 android:orientation="vertical"
7 >
8
9 <SurfaceView
10 android:id="@+id/surfaceview"
11 android:layout_width="fill_parent"
12 android:layout_height="wrap_content"
13 android:layout_above="@+id/line"
14 android:layout_alignParentTop="true"
15 />
16
17 <LinearLayout
18 android:id="@+id/line"
19 android:layout_width="fill_parent"
20 android:layout_height="wrap_content"
21 android:layout_alignParentBottom="true"
22 >
23
24 <Button
25 android:id="@+id/flushbutton"
26 android:layout_width="fill_parent"
27 android:layout_height="wrap_content"
28 android:layout_weight="1"
29 android:text="清屏"
30 />
31
32 <Button
33 android:id="@+id/colorbutton"
34 android:layout_width="fill_parent"
35 android:layout_height="wrap_content"
36 android:layout_weight="1"
37 android:text="颜色"
38 />
39 </LinearLayout>
40 </RelativeLayout>
接着,修改MyWallActivity.java文件,最主要是覆写了onTouchEvent()函数,在这个函数里过滤出触屏拖动事件,然后获取其相应的坐标和画线,关于SurfaceView的用法在基础篇里有讲到。完整的内容如下:
1 package com.nan.wall;
2
3 import android.app.Activity;
4 import android.app.AlertDialog;
5 import android.app.Dialog;
6 import android.content.DialogInterface;
7 import android.graphics.Canvas;
8 import android.graphics.Color;
9 import android.graphics.Paint;
10 import android.graphics.Rect;
11 import android.os.Bundle;
12 import android.view.MotionEvent;
13 import android.view.SurfaceHolder;
14 import android.view.SurfaceView;
15 import android.view.View;
16 import android.widget.Button;
17
18 public class MyWallActivity extends Activity
19 {
20 private SurfaceView mSurfaceView = null;
21 private SurfaceHolder mSurfaceHolder = null;
22 private Button cleanButton = null;
23 private Button colorButton = null;
24
25 private float oldX = 0f;
26 private float oldY = 0f;
27
28 private boolean canDraw = false;
29 private Paint mPaint = null;
30 //用来记录当前是哪一种颜色
31 private int whichColor = 0;
32
33 /** Called when the activity is first created. */
34 @Override
35 public void onCreate(Bundle savedInstanceState)
36 {
37 super.onCreate(savedInstanceState);
38 setContentView(R.layout.main);
39
40 mSurfaceView = (SurfaceView)this.findViewById(R.id.surfaceview);
41 mSurfaceHolder = mSurfaceView.getHolder();
42
43 mPaint = new Paint();
44 //画笔的颜色
45 mPaint.setColor(Color.RED);
46 //画笔的粗细
47 mPaint.setStrokeWidth(2.0f);
48
49 cleanButton = (Button)this.findViewById(R.id.flushbutton);
50 //按钮监听
51 cleanButton.setOnClickListener(new View.OnClickListener()
52 {
53
54 @Override
55 public void onClick(View v)
56 {
57 // TODO Auto-generated method stub
58 //锁定整个SurfaceView
59 Canvas mCanvas = mSurfaceHolder.lockCanvas();
60 mCanvas.drawColor(Color.BLACK);
61 //绘制完成,提交修改
62 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
63 //重新锁一次
64 mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
65 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
66 }
67 });
68
69 colorButton = (Button)this.findViewById(R.id.colorbutton);
70 //按钮监听
71 colorButton.setOnClickListener(new View.OnClickListener()
72 {
73
74 @Override
75 public void onClick(View v)
76 {
77 // TODO Auto-generated method stub
78 Dialog mDialog = new AlertDialog.Builder(MyWallActivity.this)
79 .setTitle("颜色设置")
80 .setSingleChoiceItems(new String[]{"红色","绿色","蓝色"}, whichColor, new DialogInterface.OnClickListener()
81 {
82
83 @Override
84 public void onClick(DialogInterface dialog, int which)
85 {
86 // TODO Auto-generated method stub
87 switch(which)
88 {
89 case 0:
90 {
91 //画笔的颜色
92 mPaint.setColor(Color.RED);
93 whichColor = 0;
94 break;
95 }
96 case 1:
97 {
98 //画笔的颜色
99 mPaint.setColor(Color.GREEN);
100 whichColor = 1;
101 break;
102 }
103 case 2:
104 {
105 //画笔的颜色
106 mPaint.setColor(Color.BLUE);
107 whichColor = 2;
108 break;
109 }
110 }
111 }
112 })
113 .setPositiveButton("确定", new DialogInterface.OnClickListener()
114 {
115
116 @Override
117 public void onClick(DialogInterface dialog, int which)
118 {
119 // TODO Auto-generated method stub
120 dialog.dismiss();
121 }
122 })
123 .create();
124 mDialog.show();
125 }
126 });
127
128 }
129
130
131 @Override
132 public boolean onTouchEvent(MotionEvent event)
133 {
134 //获取x坐标
135 float x = event.getX();
136 //获取y坐标(不知道为什么要减去一个偏移值才对得准屏幕)
137 float y = event.getY()-50;
138
139 //第一次进来先不管
140 if(canDraw)
141 {
142 //获取触屏事件
143 switch(event.getAction())
144 {
145 //如果是拖动事件
146 case MotionEvent.ACTION_MOVE:
147 {
148
149 //锁定整个SurfaceView
150 Canvas mCanvas = mSurfaceHolder.lockCanvas();
151 mCanvas.drawLine(x, y, oldX, oldY, mPaint);
152 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
153 //重新锁一次
154 mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
155 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
156 break;
157 }
158 }
159
160 }
161 //保存目前的x坐标值
162 oldX = x;
163 //保存目前的y坐标值
164 oldY = y;
165
166 canDraw = true;
167
168 return true;
169 }
170
171 }
好了,在模拟器上运行效果如下:
在真机上运行效果如下:
呵呵,写得比较丑。
在获取了Y坐标后减去一个偏移值50,这个值是我直接猜出来的,没想到在模拟器和真机上定位得还蛮准的,哈哈。当然这个应用的功能不多,不过有兴趣的话可以再完善它,希望能起到抛砖引玉的作用。