4.2.1 触摸事件

   为了开始实现这个应用程序,需要了解当用户触及触摸屏时Android将如何通知我们。能够处理这种情况之后,就可以允许用户使用他或她的手指在触摸屏上进行绘图。

   在Android上使用的许多UI元素都继承自View类。由于正在使用一个来自位图对象的Canvas对象,且该位图对象在ImageView中显示,因此有必要看看该ImageView是否可以帮助检测用户触摸的位置。

   幸运的是,View类是支持触摸的。它有一个方法,允许指定哪些类应该接收任何它获得的触摸事件。该方法是setOnClickListener,其接受一个实现OnTouchListener接口的对象作为参数。

   为了使活动实现OnTouchListener,可以声明它并创建一个称为onTouch的方法。

 1 public class SimpleFingerDraw extends Activity implements OnTouchListener {
 2     private ImageView imageView;
 3     private Bitmap bitmap;
 4     private Canvas canvas;
 5     private Paint paint;
 6     
 7     @Override
 8     protected void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.simplefingerdraw);
11         imageView=(ImageView) findViewById(R.id.ImageView);
12         Display currentDisplay=getWindowManager().getDefaultDisplay();
13         float dw=currentDisplay.getWidth();
14         float dh=currentDisplay.getHeight();
15         bitmap=Bitmap.createBitmap((int)dw, (int)dh, Bitmap.Config.ARGB_8888);
16         canvas=new Canvas(bitmap);
17         paint=new Paint();
18         paint.setColor(Color.GREEN);
19         imageView.setImageBitmap(bitmap);
20         imageView.setOnTouchListener(this);
21     }
22 
23     @Override
24     public boolean onTouch(View v, MotionEvent event) {
25         return false;
26     }
27 }

     现在,每当触摸ImageView时,都将调用活动中的onTouch方法。

     通过查看传递onTouch方法中的MotionEvent对象,可以确定发生了哪种类型的触摸。为此,需要调用该对象上的getAction方法。getAction方法将返回在MotionEvent类中定义的4个常量值之一。

     MotionEvent.ACTION_DOWN:这表明视图已经接收一次触摸。

     MotionEvent.ACTION_UP:这表明视图已经停止接收一次触摸。

     MotionEvent.ACTION_MOVE:这表明发生一次触摸之后,在ACTION_UP事件之前发生了某种移动。

     MotionEvent.ACTION_CANCEL:这表明触摸已经被取消,因此应该忽略它。

     此外,还可以调用MotionEvent对象上的getX和getY方法来确定触摸事件发生的位置。

     下面是对onTouch方法的更新。其考虑了不同事件的可能性,同时在触摸和释放触摸之间绘制直线:

 1     private float downx=0;
 2     private float downy=0;
 3     private float upx=0;
 4     private float upy=0;
 5     @Override
 6     public boolean onTouch(View v, MotionEvent event) {
 7         switch (event.getAction()) {
 8         case MotionEvent.ACTION_DOWN:
 9             downx=event.getX();
10             downy=event.getY();
11             break;
12         case MotionEvent.ACTION_MOVE:
13                 
14                 break;
15         case MotionEvent.ACTION_UP:
16             upx=event.getX();
17             upy=event.getY();
18             canvas.drawLine(downx, downy, upx, upy, paint);
19             imageView.invalidate();
20             break;
21         case MotionEvent.ACTION_CANCEL:
22             
23             break;
24         default:
25             break;
26         }
27         return true;
28     }

     你会注意到关于此代码的一下几点内容。首先,对ACTION_MOVE或ACTION_CANCEL事件不做任何事情。在ACTION_DOWN事件中,只是将downx和downy变量设置为触摸的X和Y位置。而在ACTION_UP事件中,将upx和upy设置为释放触摸事件的X和Y位置,然后调用Canvas对象上的drawLine函数。同时,还需要调用ImageView上的invalidate方法,以使该对象重新绘制到屏幕上。否则,我们将看不到在位图Canvas对象上绘制的新直线。最后,返回true而不是false。这将告诉Android,一旦事件开始就需要继续接收触摸事件。

    这个绘图应用程序非常适合于从按下手指的点到抬起手指的点绘制直线。如果希望能够随着手指一动绘制的直线,就必须同时在ACTION_MOVE事件中实现绘制代码。

1        case MotionEvent.ACTION_MOVE:
2             upx=event.getX();
3             upy=event.getY();
4             canvas.drawLine(downx, downy, upx, upy, paint);
5             imageView.invalidate();
6             downx=upx;
7             downy=upy;
8             break;

    在这个修订的示例中,在ACTION_MOVE事件中捕获upx和upy,绘制直线,然后将downx和downy变量设置为相同的位置(记住,在ACTION_DOWN事件中,直线的起始点由downx和downy定义)。这将使得直线绘制应用程序能够在屏幕上跟踪手指运动。

原文地址:https://www.cnblogs.com/ZSS-Android/p/3937314.html