Telegram阅读心得---页面结构(2)

Telegram阅读心得---页面结构(2)

Telegram阅读心得---页面结构(1)
今天我看一看那个,打开telegram能够第一眼看到的那个欢迎页
先提出这次的问题

问题 我对页面的滑动动画感兴趣,我想想看看那个动画是怎么实现的?

首先我要找到这个页面


欢迎页

string.xml中搜索这段图中的这段文本

The world's fastest messaging app.It is free and secure.

就可以找到它在app中出现的相应位置IntroActivity
同样的,这个页面也是通过代码的方式加载的页面.
页面元素比较简单,结构也比较简单.根布局是一个scrollview,在scrollview中用frameLayout承载了viewPager,顶部的动画textureView,底部的开始按钮textView,以及中间的一个自定义的viewpager指示器BottomPagesView.

UTOOLS1554879470986.png

可以一眼看出,指示器的滚动变化,文字的滚动是与viewpager相关的.

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //这里随着viewpager的滚动,通知指示器变化
                bottomPages.setPageOffset(position, positionOffset);
                //调用了一个native的方法
                Intro.setScrollOffset(offset);
                ......
            }
            ......
}

那顶部的图标的变化是怎么实现的呢?
首先顶部的动画是基于TextureView来实现的,来看一下这个textureview做了些什么

textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                if (eglThread == null && surface != null) {
                    eglThread = new EGLThread(surface);
                    eglThread.setSurfaceTextureSize(width, height);
                    //在这里启动了一个任务
                    eglThread.postRunnable(() -> eglThread.drawRunnable.run());
                }
            }

        ......

这里生成了一个EGLThread对象.
这个EGLThread是个什么东西呢
EGLThread继承自DispatchQueue,而DispatchQueue继承自Thread.
EGLThread中有一个EGL10,这个时候我想到,这个动画很有可能是native实现的.惊了~
接着往下看,确实是这个样子.

看线程中的这个任务eglThread.postRunnable(() -> eglThread.drawRunnable.run());做的内容

private Runnable drawRunnable = new Runnable() {
            @Override
            public void run() {
                ......
                float time = (System.currentTimeMillis() - currentDate) / 1000.0f;
                Intro.setPage(currentViewPagerPage);
                Intro.setDate(time);
                Intro.onDrawFrame();
              
                egl10.eglSwapBuffers(eglDisplay, eglSurface);
              //这里每16毫秒就执行这个任务,是不是能里面想到,Android上的要想达到60帧/s的流畅显示,那么每一帧的渲染时间不能高于16ms呢
                postRunnable(() -> drawRunnable.run(), 16);
            }
        };

那么这个动画的执行流程,就是这样子的


动画的执行流程

这样子就实现了稳定的60帧的动画绘制
我并没有认真看native层是如何做出如此精细的动画,将近3000行的c代码,来做出精细的东西.只能说打内心的佩服了.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 自己总结的Android开源项目及库。 github排名https://github.com/trending, ...
    AllenJuns阅读 15,158评论 13 372
  • 自己总结的Android开源项目及库。 github排名https://github.com/trending,g...
    passiontim阅读 7,380评论 1 26
  • https://github.com/7heaven/bitmapMesh Android开源项目及库整理总结 字...
    奈何心善阅读 10,147评论 2 40
  • 2018.04.18 血刀老祖真是坏得顶天立地。 连城诀(世纪新修版)一乡下人进城半个月之后,戚长发带同徒儿狄云、...
    摹喵居士阅读 2,435评论 0 0
  • 今天,注册了简书,不为了别的,只为了和大家分享ios、以及移动开发的各种秘籍和技巧,顺便也是给自己一个监督和记录,...
    __CodeR阅读 1,702评论 0 0

友情链接更多精彩内容