返回顶部
首页 > 资讯 > 移动开发 >Android自定义view之3D正方体效果实例
  • 498
分享到

Android自定义view之3D正方体效果实例

2024-04-02 19:04:59 498人浏览 泡泡鱼
摘要

目录前言一、小提二、将传感器改成事件分发机制三、使用四、源码总结前言 在之前写了一篇关于3D效果的文章,借助传感器展示,有小伙伴问可不可以改成手势滑动操作(事件分发),所以出一篇文

前言

在之前写了一篇关于3D效果的文章,借助传感器展示,有小伙伴问可不可以改成手势滑动操作(事件分发),所以出一篇文章

传感器相关文章链接:Android 3D效果的实现

一、小提

相对于常见的自定义view而言,继承的GLSurfaceView只有两个构造函数。可以理解为没有提供获取自定义属性的方法。


    public TouchSurfaceView(Context context) {
        super(context);
    }

    public TouchSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

二、将传感器改成事件分发机制


    @Override
    public boolean onTouchEvent(MotionEvent e) {
        float x = e.getX();
        float y = e.getY();
        switch (e.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float dx = x - mPreviousX;
                float dy = y - mPreviousY;
                mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR;
                mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR;
                requestRender();
        }
        mPreviousX = x;
        mPreviousY = y;
        return true;
    }

要注意还有一个滚动球事件


    @Override
    public boolean onTrackballEvent(MotionEvent e) {
        mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
        mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
        requestRender();
        return true;
    }

三、使用


  mGLSurfaceView = new TouchSurfaceView(this);
        setContentView(mGLSurfaceView);
        mGLSurfaceView.requestFocus();
        mGLSurfaceView.setFocusableInTouchMode(true);

注意要在对应生命周期中处理


    @Override
    protected void onResume() {
        super.onResume();
        mGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLSurfaceView.onPause();
    }

四、源码

TouchSurfaceView.java

除去前面的修改部分,其他大多与链接文章相同,仅将传感器改成了事件分发。(代码中难点有注释)


public class TouchSurfaceView extends GLSurfaceView {
    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
    private final float TRACKBALL_SCALE_FACTOR = 36.0f;
    private CubeRenderer mRenderer;
    private float mPreviousX;
    private float mPreviousY;

    public TouchSurfaceView(Context context) {
        super(context);
        mRenderer = new CubeRenderer();
        setRenderer(mRenderer);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }

    public TouchSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onTrackballEvent(MotionEvent e) {
        mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
        mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
        requestRender();
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        float x = e.getX();
        float y = e.getY();
        switch (e.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float dx = x - mPreviousX;
                float dy = y - mPreviousY;
                mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR;
                mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR;
                requestRender();
        }
        mPreviousX = x;
        mPreviousY = y;
        return true;
    }


    private class CubeRenderer implements GLSurfaceView.Renderer {

        private Cube mCube;
        public float mAngleX;
        public float mAngleY;
        public CubeRenderer() {
            mCube =new Cube();
        }

        public void onDrawFrame(GL10 gl) {
// | GL10.GL_DEPTH_BUFFER_BIT
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glLoadIdentity();
            gl.glTranslatef(0, 0, -3.0f);
            gl.glRotatef(mAngleX, 0, 1, 0);
            gl.glRotatef(mAngleY, 1, 0, 0);
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
            mCube.draw(gl);
        }


        @Override
        public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) {
            gl.glDisable(GL10.GL_DITHER);
            gl.glClearColor(1,1,1,1);
        }

        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
            //设置投影矩阵。但并不需要在每次绘制时都做,通常情况下,当视图调整大小时,需要设置一个新的投影。
            float ratio = (float) width / height;
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
        }

    }



    public class Cube {
        //opengl坐标系中采用的是3维坐标:
        private FloatBuffer mVertexBuffer;
        private FloatBuffer mColorBuffer;
        private ByteBuffer mIndexBuffer;

        public Cube() {
            final float vertices[] = {
                    -1, -1, -1,		 1, -1, -1,
                    1,  1, -1,	    -1,  1, -1,
                    -1, -1,  1,      1, -1,  1,
                    1,  1,  1,     -1,  1,  1,
            };

            final float colors[] = {
                    0,  1,  1,  1,  1,  1,  1,  1,
                    1,  1,  0,  1,  1,  1,  1,  1,
                    1,  1,  1,  1,  0,  1,  1,  1,
                    1,  1,  1,  1,  1,  1,  0,  1,
            };

            final byte indices[] = {
                    0, 4, 5,    0, 5, 1,
                    1, 5, 6,    1, 6, 2,
                    2, 6, 7,    2, 7, 3,
                    3, 7, 4,    3, 4, 0,
                    4, 7, 6,    4, 6, 5,
                    3, 0, 1,    3, 1, 2
            };

            ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
            vbb.order(ByteOrder.nativeOrder());
            mVertexBuffer = vbb.asFloatBuffer();
            mVertexBuffer.put(vertices);
            mVertexBuffer.position(0);

            ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
            cbb.order(ByteOrder.nativeOrder());
            mColorBuffer = cbb.asFloatBuffer();
            mColorBuffer.put(colors);
            mColorBuffer.position(0);

            mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
            mIndexBuffer.put(indices);
            mIndexBuffer.position(0);
        }

        public void draw(GL10 gl) {
            //启用服务器端GL功能。
            gl.glEnable(GL10.GL_CULL_FACE);
            //定义多边形的正面和背面。
            //参数:
            //mode——多边形正面的方向。GL_CW和GL_CCW被允许,初始值为GL_CCW。
            gl.glFrontFace(GL10.GL_CW);
            //选择恒定或光滑着色模式。
            //GL图元可以采用恒定或者光滑着色模式,默认值为光滑着色模式。当图元进行光栅化的时候,将引起插入顶点颜色计算,不同颜色将被均匀分布到各个像素片段。
            //参数:
            //mode——指明一个符号常量来代表要使用的着色技术。允许的值有GL_FLAT 和GL_SMOOTH,初始值为GL_SMOOTH。
            gl.glShadeModel(GL10.GL_SMOOTH);
            //定义一个顶点坐标矩阵。
            //参数:
            //
            //size——每个顶点的坐标维数,必须是2, 3或者4,初始值是4。
            //
            //type——指明每个顶点坐标的数据类型,允许的符号常量有GL_BYTE, GL_SHORT, GL_FIXED和GL_FLOAT,初始值为GL_FLOAT。
            //
            //stride——指明连续顶点间的位偏移,如果为0,顶点被认为是紧密压入矩阵,初始值为0。
            //
            //pointer——指明顶点坐标的缓冲区,如果为null,则没有设置缓冲区。
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
            //定义一个颜色矩阵。
            //size指明每个颜色的元素数量,必须为4。type指明每个颜色元素的数据类型,stride指明从一个颜色到下一个允许的顶点的字节增幅,并且属性值被挤入简单矩阵或存储在单独的矩阵中(简单矩阵存储可能在一些版本中更有效率)。
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
            //由矩阵数据渲染图元
            //可以事先指明独立的顶点、法线、颜色和纹理坐标矩阵并且可以通过调用glDrawElements方法来使用它们创建序列图元。
            gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
        }
    }
}

MainActivity.java


public class MainActivity extends AppCompatActivity {
    private GLSurfaceView mGLSurfaceView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLSurfaceView = new TouchSurfaceView(this);
        setContentView(mGLSurfaceView);
        mGLSurfaceView.requestFocus();
        mGLSurfaceView.setFocusableInTouchMode(true);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLSurfaceView.onPause();
    }


}

总结

到此这篇关于Android自定义view之3D正方体效果的文章就介绍到这了,更多相关Android自定义view之3D正方体内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android自定义view之3D正方体效果实例

本文链接: https://lsjlt.com/news/133237.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android自定义view之3D正方体效果实例
    目录前言一、小提二、将传感器改成事件分发机制三、使用四、源码总结前言 在之前写了一篇关于3D效果的文章,借助传感器展示,有小伙伴问可不可以改成手势滑动操作(事件分发),所以出一篇文...
    99+
    2024-04-02
  • Android自定义View实现闪耀字体效果
    本文实例为大家分享了闪耀字体效果的具体代码,供大家参考,具体内容如下 import android.content.Context; import android.graph...
    99+
    2022-06-06
    view 字体 Android
  • android自定义view实现钟表效果
    本文实例为大家分享了android view实现钟表的具体代码,供大家参考,具体内容如下 先看效果图: 自定义view大家肯定已经不陌生了,所以直接今天直接步入正题:如何利用...
    99+
    2022-06-06
    view Android
  • Android自定义View实现扫描效果
    本文实例为大家分享了Android自定义View实现扫描效果的具体代码,供大家参考,具体内容如下 演示效果如下: 实现内容: 1、控制动画是竖向或者横向 2、控制动画初始是从底部/...
    99+
    2024-04-02
  • Android自定义View实现时钟效果
    本文实例为大家分享了Android自定义View实现时钟效果的具体代码,供大家参考,具体内容如下 自定义时钟 初学自定义View,先画一个不太成熟的时钟(甚至只有秒针) 时钟效果 ...
    99+
    2024-04-02
  • android 自定义圆角button效果的实例代码(自定义view Demo)
    概述 在平时开发过程中经常会碰到需要使用圆角button的情况,一般也会包括很多其他小功能,比如要在里面添加img,设置不同的圆角大小等。 针对这样的场景,直接使用创建多个s...
    99+
    2022-06-06
    button 自定义 view demo 自定义view Android
  • Android自定义View实现折线图效果
    下面就是结果图(每种状态用一个表情图片表示): 一、主页面的布局文件如下: <RelativeLayout xmlns:android="http://schema...
    99+
    2022-06-06
    折线图 view Android
  • Android自定义View实现打字机效果
    一、先来看看效果演示 二、实现原理: 这个其实不难实现,通过一个定时器不断调用TextView的setText就行了,在setText的时候播放打字的音效。 具体代码如下:...
    99+
    2022-06-06
    view 打字机 Android
  • Android中自定义view实现侧滑效果
    效果图: 看网上的都是两个view拼接,默认右侧的不显示,水平移动的时候把右侧的view显示出来。但是看最新版QQ上的效果不是这样的,但给人的感觉却很好,所以献丑来一发比较高...
    99+
    2022-06-06
    view 自定义view Android
  • Android自定义Animation实现View摇摆效果
    使用自定义Animation,实现View的左右摇摆效果,如图所示: 代码很简单,直接上源码 activity_maini.xml布局文件: <?xml v...
    99+
    2022-06-06
    view animation Android
  • Android自定义view实现半圆环效果
    本文实例为大家分享了Android自定义view实现半圆环的具体代码,供大家参考,具体内容如下 1.自定义属性 <declare-styleable name="Semicir...
    99+
    2024-04-02
  • Android自定义View实现标签流效果
    本文实例为大家分享了Android自定义View实现标签流效果的具体代码,供大家参考,具体内容如下 一、概述 Android自定义View实现标签流效果,一行放不下时会自动换行,用户...
    99+
    2024-04-02
  • Android自定义view实现输入框效果
    本文实例为大家分享了Android自定义view实现输入框的具体代码,供大家参考,具体内容如下 自定义输入框的View package com.fenghongzhang.day...
    99+
    2024-04-02
  • Android自定义View实现水波纹效果
    介绍:水波纹散开效果的控件在 App 里面还是比较常见的,例如 网易云音乐歌曲识别,附近搜索场景。看下实现的效果:实现思路: 先将最大圆半径与最小圆半径间距分成几等份,从内到外,Paint 透明度依次递减,绘制出同心圆,然后不断的改变这些同...
    99+
    2023-05-30
    android view 水波纹
  • Android自定义View实现弹性小球效果
    照例先看效果图 自定义代码示例 public class BezierView extends View { Paint paint;//画笔 Path path;//...
    99+
    2022-06-06
    弹性 view Android
  • Android自定义View实现圆环交替效果
    下面请先看效果图:    看上去是不很炫的样子,它的实现上也不是很复杂,重点在与onDraw()方法的绘制。 首先是我们的attrs文件: <?xml ver...
    99+
    2022-06-06
    view Android
  • Android自定义View实现水面上涨效果
    实现效果如下: 实现思路: 1、如何实现圆中水面上涨效果:利用Paint的setXfermode属性为PorterDuff.Mode.SRC_IN画出进度所在的矩形与圆的交...
    99+
    2022-06-06
    view Android
  • Android自定义View控件实现刷新效果
    三种得到LinearInflater的方法 a. LayoutInflater inflater = getLayoutInflater(); b. LayoutInflate...
    99+
    2022-06-06
    view Android
  • Android自定义view实现滑动解锁效果
    本文实例为大家分享了Android自定义view实现滑动解锁的具体代码,供大家参考,具体内容如下 1. 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 2. ...
    99+
    2024-04-02
  • Android如何实现自定义view画圆效果
    这篇文章主要介绍了Android如何实现自定义view画圆效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。看图代码:package sjx.com.custonv...
    99+
    2023-05-30
    android view
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作