当在自定义View或者做游戏的时候,我们常常会用到键盘触发事件和屏幕触发事件!在自定义的View里的键盘触发事件(比如:onKeyDown(int keyCode, KeyEvent event))和屏幕触发事件(onTouchEvent(MotionEvent event))和activity里的键盘触发事件(比如:onKeyDown(int keyCode, KeyEvent event))和屏幕触发事件(onTouchEvent(MotionEvent event))是怎么样交互的呢?是怎样的一个运行原理呢?下面来看看:
1、屏幕触发事件:哪个activity或者视图,控件在最上层就最先触发这个控件里的屏幕触发事件,返回值如果是默认或者false就会一层一层的往下传递!如果返回值是true,则在执行完动作之后不会往下传递!
2、键盘触发事件:这个原理和屏幕触发事件差不多,但是不同的时,在没有设置控件处于焦点时,一般按键盘里的按键触发的是activity里的键盘触发事件(比如:onKeyDown(int keyCode, KeyEvent event))。
下面来举个例子:
比如在做游戏的时候,我们经常自定义视图,我们一般都喜欢和使用触发本视图(GameView)里的键盘触发事件和屏幕触发事件,但是比如:onKeyDown(int keyCode, KeyEvent event)),一般我们按键盘的时候直接触发的是activity里的键盘触发事件,怎样让它直接触发(GameView)里的键盘触发事件呢?
第一种方法:
例子1:
1 package net.loonggg.project; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.KeyEvent; 6 import android.view.MotionEvent; 7 8 public class MainActivity extends Activity { 9 private GameView gameView; 10 11 @Override 12 public void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 gameView = new GameView(this); 15 setContentView(gameView); 16 } 17 18 @Override 19 public boolean onKeyDown(int keyCode, KeyEvent event) { 20 System.out.println("MainActivity:" + " keyCode:" + keyCode + " evnet:" 21 + event); 22 return super.onKeyDown(keyCode, event); 23 } 24 25 @Override 26 public boolean onTouchEvent(MotionEvent event) { 27 System.out.println("MainActivity:" + " event:" + event + " x:" 28 + event.getX() + " y:" + event.getY()); 29 return super.onTouchEvent(event); 30 } 31 } 32 33 34 35 36 package net.loonggg.project; 37 38 import android.content.Context; 39 import android.graphics.Canvas; 40 import android.graphics.Color; 41 import android.graphics.Paint; 42 import android.view.KeyEvent; 43 import android.view.MotionEvent; 44 import android.view.View; 45 46 public class GameView extends View { 47 private Paint paint; 48 private int pointX; 49 private int pointY; 50 51 public GameView(Context context) { 52 super(context); 53 // 设置GameView获得焦点 54 this.setFocusable(true); 55 paint = new Paint(); 56 paint.setColor(Color.YELLOW); 57 Thread t = new Thread(new MyThread()); 58 t.start(); 59 } 60 61 @Override 62 protected void onDraw(Canvas canvas) { 63 super.onDraw(canvas); 64 canvas.drawCircle(pointX, pointY, 15, paint); 65 } 66 67 class MyThread implements Runnable { 68 69 @Override 70 public void run() { 71 while (true) { 72 try { 73 Thread.sleep(3000); 74 pointY = pointY + 10; 75 pointX = pointX + 10; 76 if (pointX > 200) { 77 break; 78 } 79 } catch (InterruptedException e) { 80 e.printStackTrace(); 81 } 82 83 GameView.this.postInvalidate(); 84 } 85 } 86 87 } 88 89 @Override 90 public boolean onKeyDown(int keyCode, KeyEvent event) { 91 System.out.println("GameView:" + " keyCode:" + keyCode + " evnet:" 92 + event); 93 //此事件不会传播出去 94 return true; 95 } 96 97 @Override 98 public boolean onTouchEvent(MotionEvent event) { 99 System.out.println("GameView:" + " event:" + event + " x:" 100 + event.getX() + " y:" + event.getY()); 101 //此事件不会传播出去 102 return true; 103 } 104 105 }
第二种方法:
1 package net.loonggg.project; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.KeyEvent; 6 import android.view.MotionEvent; 7 8 public class MainActivity extends Activity { 9 private GameView gameView; 10 11 @Override 12 public void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 gameView = new GameView(this); 15 setContentView(gameView); 16 } 17 18 @Override 19 public boolean onKeyDown(int keyCode, KeyEvent event) { 20 System.out.println("MainActivity:" + " keyCode:" + keyCode + " evnet:" 21 + event); 22 //把事件传递给gameView 23 gameView.onKeyDown(keyCode, event); 24 return super.onKeyDown(keyCode, event); 25 } 26 27 @Override 28 public boolean onTouchEvent(MotionEvent event) { 29 System.out.println("MainActivity:" + " event:" + event + " x:" 30 + event.getX() + " y:" + event.getY()); 31 //把事件传递给gameView 32 gameView.onTouchEvent(event); 33 return super.onTouchEvent(event); 34 } 35 } 36 37 38 39 package net.loonggg.project; 40 41 import android.content.Context; 42 import android.graphics.Canvas; 43 import android.graphics.Color; 44 import android.graphics.Paint; 45 import android.view.KeyEvent; 46 import android.view.MotionEvent; 47 import android.view.View; 48 49 public class GameView extends View { 50 private Paint paint; 51 private int pointX; 52 private int pointY; 53 54 public GameView(Context context) { 55 super(context); 56 paint = new Paint(); 57 paint.setColor(Color.YELLOW); 58 Thread t = new Thread(new MyThread()); 59 t.start(); 60 } 61 62 @Override 63 protected void onDraw(Canvas canvas) { 64 super.onDraw(canvas); 65 canvas.drawCircle(pointX, pointY, 15, paint); 66 } 67 68 class MyThread implements Runnable { 69 70 @Override 71 public void run() { 72 while (true) { 73 try { 74 Thread.sleep(3000); 75 pointY = pointY + 10; 76 pointX = pointX + 10; 77 if (pointX > 200) { 78 break; 79 } 80 } catch (InterruptedException e) { 81 e.printStackTrace(); 82 } 83 84 GameView.this.postInvalidate(); 85 } 86 } 87 88 } 89 90 @Override 91 public boolean onKeyDown(int keyCode, KeyEvent event) { 92 System.out.println("GameView:" + " keyCode:" + keyCode + " evnet:" 93 + event); 94 return super.onKeyDown(keyCode, event); 95 } 96 97 @Override 98 public boolean onTouchEvent(MotionEvent event) { 99 System.out.println("GameView:" + " event:" + event + " x:" 100 + event.getX() + " y:" + event.getY()); 101 return super.onTouchEvent(event); 102 } 103 104 }
在这里,推荐使用第二种方法,因为第一种方法有的模拟器不能够使用!