手摸手带你用 VideoView 实现英语流利说炫酷引导页
2016-08-29 15:13 阅读(261)

项目地址:https://github.com/JeasonWong/LiulishuoPreview

效果图:

Markdown


一直听说英语流利说是个做的非常不错的app,于是乎抱着崇拜的心态下了一个瞅瞅,在打开app后就被引导页吸引了,继续抱着崇拜的心态去思考这是如何实现的。

刚开始的思路

为了证实自己的思路,继续抱着崇拜的心态解压了apk,发现果然啊,有个18s的mp4文件,拿到这个后再想实现这个效果就太尼玛容易了。

ps:我觉得单独这样拿文件并开源是种不太好的行为,所以向目前在流利说的前同事稍微请示了下,心里踏实些~

下面开始手摸手分析:
- 18s的动画分成了三部分
- 引导页也是三页,而且每一页都在循环对应的6s
- 播放mp4可以用VideoView
- 播放至指定位置可以用VideoView暴露的seekTo(int msec)

所有问题迎刃而解,so easy啊。

那么可以开始手摸手撸码了:

一、视频文件放入src/raw文件夹内

插句嘴,这里可以温习下常见面试题,src/raw与assets的区别?

放入后读取相关文件:

/**
     * 获取video文件的路径
     *
     * @return 路径
     */
    private String getVideoPath() {
        return "android.resource://" + this.getPackageName() + "/" + R.raw.intro_video;
    }

二、VideoView准备播放

mVideoView = (PreviewVideoView) findViewById(R.id.vv_preview);
mVideoView.setVideoURI(Uri.parse(getVideoPath()));

三、轮询每一页的6s

private Subscription mLoop;

    /**
     * 开启轮询
     */
    private void startLoop() {
        if (null != mLoop) {
            mLoop.unsubscribe();
        }
        mLoop = Observable.interval(0, 6 * 1000, TimeUnit.MILLISECONDS)
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        mVideoView.seekTo(mCurrentPage * 6 * 1000);
                        if (!mVideoView.isPlaying()) {
                            mVideoView.start();
                        }
                    }
                });
    }

关于何时startLoop我就不赘述了,一个是启动后,一个是ViewPager滑动后。

看似好像完成了所有操作,其实不然,最后一步尤为重要!

四、确保VideoView全屏且尽量不拉伸

冲着这个标题就知道要重写VideoView的onMeasure()方法了。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int w = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(w, (int) (w / 0.56f));
    }

宽度保持全屏,高度用宽度/0.56,很多人会问,0.56哪来的?请看图:

Markdown


mp4文件是1080*1920的,宽/长约等于0.56,很简单吧。

以上就是实现英语流利说炫酷引导页的主要步骤,其实整个过程最难的一点就是这个mp4文件的制作,不得不给流利说的设计师们点个赞!大写的66666。