为了方便没有准备好梯子的同学,我把项目在CSDN上打包下载,不过不会继续更新(保留在初始版本)
除了根据传感器来控制以外,还应该支持使用手指平移的操作
触控事件的分发与监听
初学安卓时应该经常会看到这样的代码:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
当一个点击事件被确认时,会触发按钮的点击事件回调逻辑
触控事件都有哪些呢?一般来说主要有这些:
* MotionEvent.ACTION_DOWN
* MotionEvent.ACTION_MOVE
* MotionEvent.ACTION_UP
如果涉及到多指触控,那么就会有不同的Pointer来表示不同的手指的触控事件。
通过给我们的glSurfaceView设置一个监听器,我们可以直接拦截glSurfaceView上的触控事件
glSurfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Logger.logTouchEvent(v,event);
}
});
可以这样查看触控事件类型
int action = event.getActionMasked()
或者可以直接打印出详细的触控信息:
public static void logTouchEvent(View v, MotionEvent event){
StringBuilder result=new StringBuilder();
result.append(v.toString()+" \n");
result.append("Action: ").append(event.getAction()).append("\n");
result.append("Location: ").append(event.getX()).append(" x ")
.append(event.getY()).append("\n");
result.append("Edge flags: ").append(event.getEdgeFlags());
result.append("\n");
result.append("Pressure: ").append(event.getPressure());
result.append(" ").append("Size: ").append(event.getSize());
result.append("\n").append("Down time: ");
result.append(event.getDownTime()).append("ms\n");
result.append("Event time: ").append(event.getEventTime());
result.append("ms").append(" Elapsed:");
result.append(event.getEventTime() - event.getDownTime());
result.append(" ms\n");
Log.d(TAG,result.toString());
}
关于触控点的坐标:手机正放(Portrait),原点在左上角,向右x增大,向下y增大
需要注意的是,我们应该加上这句话,使得onTouch能够监听ACTION_DOWN以外的事件:
glSurfaceView.setClickable(true);
关于触控事件的分发机制,网上应该能找到很多资料,就不展开讲了
单指(Scroll)事件的处理
自己记录触控事件并进行处理自然是可以的,但是SDK中已经为我们提供了一个辅助类GestureDetector:
private GestureDetector gestureDetector;
private static final float sDensity = Resources.getSystem().getDisplayMetrics().density;
private static final float sDamping = 0.2f;
private float mDeltaX;
private float mDeltaY;
private void initGestureHandler(){
mDeltaX=mDeltaY=0;
gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
mDeltaX+= distanceX / sDensity * sDamping;
mDeltaY+= distanceY / sDensity * sDamping;
return super.onScroll(e1, e2, distanceX, distanceY);
}
});
}
public boolean handleTouchEvent(MotionEvent event) {
boolean ret=ret=gestureDetector.onTouchEvent(event);
return ret;
}
sDensity
是一个与分辨率和尺寸有关的(也就是PPI)参数,因为移动距离是用像素表示的,所以应该累乘上这个参数以减小不同手机的区别,然后我们在onScroll
中把移动的距离累计起来
更新onDrawFrame
Matrix.setIdentityM(modelMatrix, 0);
Matrix.rotateM(modelMatrix, 0, mDeltaY, 1.0f, 0.0f, 0.0f);
Matrix.rotateM(modelMatrix, 0, mDeltaX, 0.0f, 1.0f, 0.0f);
修改MainActivity.java
glSurfaceView.setClickable(true);
glSurfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return glRenderer.handleTouchEvent(event);
}
});
效果预览
再来一张GIF吧