Android官方开发文档Training系列课程中文版:OpenGL绘图之响应触摸事件

原文地址:http://android.xsoftlab.net/training/graphics/opengl/touch.html

使图形按照程序设计的轨迹旋转对OpenGL来说还是不能发挥出它应有的实力。但要是能使用户可以直接控制图形的旋转,这才是OpenGL的真正目的。它真正的关键所在就是使程序可以交互式触摸。这主要靠重写GLSurfaceView的onTouchEvent()的方法来实现触摸事件的监听。

这节课将会展示如何监听触摸事件来使用户可以旋转图形。

设置触摸监听器

为了可以使OpenGL监听触摸事件,必须重写GLSurfaceView类中的onTouchEvent()方法。下面的实现展示了如何监听MotionEvent.ACTION_MOVE事件,以及如何使事件驱动图形的旋转.

private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent e) {
    // MotionEvent reports input details from the touch screen
    // and other input controls. In this case, you are only
    // interested in events where the touch position changed.
    float x = e.getX();
    float y = e.getY();
    switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dx = x - mPreviousX;
            float dy = y - mPreviousY;
            // reverse direction of rotation above the mid-line
            if (y > getHeight() / 2) {
              dx = dx * -1 ;
            }
            // reverse direction of rotation to left of the mid-line
            if (x < getWidth() / 2) {
              dy = dy * -1 ;
            }
            mRenderer.setAngle(
                    mRenderer.getAngle() +
                    ((dx + dy) * TOUCH_SCALE_FACTOR));
            requestRender();
    }
    mPreviousX = x;
    mPreviousY = y;
    return true;
}

这里需要注意的是,在计算完旋转的角度之后,这个方法调用了requestRender()方法,这个方法会通知渲染器可以渲染了。这个方法放在这个地方是最合适的,因为帧在这之前并不需要重新绘制,除非在角度上发生了变化。不管怎么样,这个方法并不会对效率有任何影响,除非你也设置了在数据发生改变的时候重新绘制的请求。这种请求通过setRenderMode()方法设置,所以要确保下面这行代码没有被注释:

public MyGLSurfaceView(Context context) {
    ...
    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

暴露旋转角度

上面的示例代码会要求提供一个公开的成员方法来暴露旋转的角度。一旦渲染代码运行在子线程当中,那么必须将这个公共成员声明为volatile。下面的代码声明了这个volatile的属性,并暴露了它的get,set方法:

public class MyGLRenderer implements GLSurfaceView.Renderer {
    ...
    public volatile float mAngle;
    public float getAngle() {
        return mAngle;
    }
    public void setAngle(float angle) {
        mAngle = angle;
    }
}

请求旋转

为了触摸事件驱动旋转,需要注释生成角度的代码,然后添加mAngle成员属性,mAngle中包含了触摸事件所生成的角度:

public void onDrawFrame(GL10 gl) {
    ...
    float[] scratch = new float[16];
    // Create a rotation for the triangle
    // long time = SystemClock.uptimeMillis() % 4000L;
    // float angle = 0.090f * ((int) time);
    Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
    // Combine the rotation matrix with the projection and camera view
    // Note that the mMVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
    // Draw triangle
    mTriangle.draw(scratch);
}

如果完成了上面所描述的步骤,那么启动程序,然后在屏幕上拖动就可以使三角形旋转起来:

时间: 2024-10-31 12:25:03

Android官方开发文档Training系列课程中文版:OpenGL绘图之响应触摸事件的相关文章

Android官方开发文档Training系列课程中文版:目录

原文地址 : http://android.xsoftlab.net/training/index.html 引言 在翻译了一篇安卓的官方文档之后,我觉得应该做一件事情,就是把安卓的整篇训练课程全部翻译成英文,供国内的开发者使用,尤其是入门开发者,虽然现在网络上有很多入门课程,但是还是依靠官方文档学习来的靠谱,安卓官方文档是一系列的课程,使每个人可以系统的掌握安卓的知识,相比其它课程来说,它为开发者提供了查缺补漏的功能. 在这里你可以领略到安卓开发世界的精彩. Tips : 同时,本目录可以作为

Android官方开发文档Training系列课程中文版:OpenGL绘图之图形绘制

原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html 如果你还不清楚如何定义图形及坐标系统,请移步:Android官方开发文档Training系列课程中文版:OpenGL绘图之图形定义. 在定义了图形之后,你接下来需要做的就是将它绘制到屏幕上.不过使用OpenGL ES 2.0 API来绘制这个图形所需要的代码量可能要比想象中的多一些,这是因为API为图形渲染管道提供了大量的控制细节. 这节课会展示如何绘制上节课所

Android官方开发文档Training系列课程中文版:OpenGL绘图之环境配置

原文地址:http://android.xsoftlab.net/training/graphics/opengl/index.html 引言 Android framework层为创建绚丽的功能性UI提供了大量的标准工具.然而,如果想要以更多方式来控制屏幕的绘制,或者在三维图形中绘制,那么就需要使用其它工具了.Android framework所提供的OpenGL ES API为我们提供了一系列的工具,这些工具可以用来显示一些高端大气.天马行空的图形,只要你能想得到,那么它就可以做得到.此外,

Android官方开发文档Training系列课程中文版:手势处理之ViewGroup的事件管理

原文地址:https://developer.android.com/training/gestures/viewgroup.html 在ViewGroup中处理触摸事件要格外小心,因为在ViewGroup中有很多子View,而这些子View对于不同的触摸事件来说是不同的目标.要确保每个View都正确的接收了相应的触摸事件. 在ViewGroup中拦截触摸事件 onInterceptTouchEvent()方法会在触摸事件到达ViewGroup的表面时调用,这包括内部的子View.如果onInt

Android官方开发文档Training系列课程中文版:通知用户之构建通知

原文地址:http://android.xsoftlab.net/training/notify-user/index.html 引言 通知用于在有事件发生时,将事情以更便捷的方式展示给用户.用户可以在他们方便的时候直接与通知交互. Notifications design guide课程讲述了如何设计有效的通知以及何时去使用它们.这节课将会学习如何实现通用的通知设计. 构建通知 这节课的实现主要基于NotificationCompat.Builder类,NotificationCompat.B

Android官方开发文档Training系列课程中文版:手势处理之多点触控处理

原文地址:http://android.xsoftlab.net/training/gestures/multi.html 多点触控是指多个手指同时触摸屏幕的情况.这节课主要学习如何检测多点触控手势. 记录多个触控点 当多根手指同时触碰到屏幕时,系统会产生以下触摸事件: ACTION_DOWN -第一个触碰到屏幕的点.它是手势的起始事件.这个触控点的指针数据在MotionEvent对象中的索引总是0. ACTION_POINTER_DOWN -除第一个触控点之外的其它点.这个触控点的指针数据的索

Android官方开发文档Training系列课程中文版:手势处理之滚动动画及Scroller

原文地址:http://android.xsoftlab.net/training/gestures/scroll.html 在Android中,滑动经常由ScrollView类来实现.任何超出容器边界的布局都应该将自己内嵌在ScrollView中,以便提供可滚动的视图效果.自定义滚动只有在特定的场景下才会被用到.这节课将会描述这样一种场景:使用scroller显示一种可滚动的效果. 你可以使用Scroller或者OverScroller来收集一些滑动动画所需要的数据.这两个类很相似,但是Ove

Android官方开发文档Training系列课程中文版:手势处理之记录手指移动的轨迹

原文地址:http://android.xsoftlab.net/training/gestures/movement.html 这节课将会学习如何在触摸事件中记录手指移动的轨迹. 当手指触摸的位置.压力或者尺寸发生变化时,ACTION_MOVE事件就会被触发.与Detecting Common Gestures中描述的一样,所有的事件都被记录在一个MotionEvent对象中. 因为基于手指的触摸并不是很精确的交互方式,所以检测触摸事件的行为需要更多的轨迹点.为了帮助APP区分基于轨迹的手势(

Android官方开发文档Training系列课程中文版:手势处理之监测通用手势

原文地址:http://android.xsoftlab.net/training/gestures/index.html 引言 这节课将会学习如何让用户通过触摸手势与APP产生交互.Android提供了许多相关API来帮助你创建.检测手势. 尽管APP不应该将触摸手势作为基本的输入特性,但是触摸手势可以使APP快速提高可操作性与吸引力. 为了提供一种一贯的,直观的用户体验,APP应当使用Android通用的触摸手势标准. 检测通用手势 当用户将一根或者多根手指放置在触摸屏上时就会产生触摸事件,