[OpenGL]从零开始写一个Android平台下的全景视频播放器——5.4 响应用户的单指触控事件(平移)

Github项目地址

为了方便没有准备好梯子的同学,我把项目在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吧
这里写图片描述

Github项目地址
回到目录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值