Android之ViewPager+VideoView引导界面

原创 2016年10月16日 10:03:57

本文主要记录一些零碎的东西

需求:
做一个可以滑动的引导界面,三页,前两页是图片,第三页是视频

思路:
使用ViewPager直接搞定,三个界面搞定
视频肯定是短视频,没有什么播放控制,就循环播放,使用VideoView就够了
先说说会遇到的问题:
1.前两页静态图片没有问题,滑第三页VideoView时,没有视频缩略图,空白界面
2.滑动到第三页后视频播放时有个黑屏时间
解决:
1.第二个好解决,VideoView extends SurfaceView 在activity上第一次加载时需要时间,
暴力解决:在第一页添加一个宽和高为0的VideoView,让SurfaceView先加载

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/guide1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/welcome1"
        android:orientation="vertical">
        <VideoView
            android:layout_width="0dp"
            android:layout_height="0dp" />
    </LinearLayout>

2.第一个问题嘛,给设置一个缩略图就解决了
布局文件里一个ImageView与VideoView相同大小

<?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <VideoView
            android:id="@+id/guide_third_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ImageView
            android:id="@+id/guide_third_video_thumbnail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            />
    </FrameLayout>

获取视频缩略图
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(this, mUri);
mImageView.setImageBitmap(mmr.getFrameAtTime());
添加ViewPager 滑动监听
ViewPager.addOnPageChangeListener,
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
在这个函数里处理缩略图的显示
public void onPageScrollStateChanged(int state) state==0 时视图准备好了
在这个函数里处理缩略图的消失

3.循环播放:

mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                     mp.setLooping(true);

            }
        });


4.发现来回切换时,尤其是切到第一页后再回到视频页,会闪一下
原来是ViewPager坑,
有个mOffscreenPageLimit 变量,默认是 1;每次翻页回来后,VideoView都会被销毁,然后重新start
ViewPager.setOffscreenPageLimit(2);//设置viewpager保留多少个显示界面

5.从资源文件里获取视频文件 /res/raw/FILE_NAME.mp4
uriPath = "android.resource://"+getPackageName()+"/raw/FILE_NAME";
mUri = Uri.parse(uriPath);

6.点击 立即体验 ,是监听touch 事件,判断触摸点坐标


全部java代码

    private void initView() {
        LayoutInflater inflater = LayoutInflater.from(this);
        views = new ArrayList<>();
        views.add(inflater.inflate(R.layout.guide_page1, null));
        views.add(inflater.inflate(R.layout.guide_page2, null));
        thirdView = inflater.inflate(R.layout.guide_page3, null);
        views.add(thirdView);
        //实例化viewpager
        vpAdapter = new ViewPagerAdapter(views);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(vpAdapter);
        viewPager.addOnPageChangeListener(pageChangeListener);
        viewPager.setPageTransformer(true, pageTransformer);
        viewPager.setOffscreenPageLimit(2);
        viewPager.setCurrentItem(0);
        mCurrentPosition = 0;

        thirdView.setOnTouchListener(GifTouch);

        initWelcomeVideo();
    }

    private void initWelcomeVideo() {

        uriPath = "android.resource://"+getPackageName()+"/raw/welcome_page3";
        mUri = Uri.parse(uriPath);
        mVideoView = (VideoView)thirdView.findViewById(R.id.guide_third_video);
        mVideoView.setVideoURI(mUri);

        mImageView = (ImageView) thirdView.findViewById(R.id.guide_third_video_thumbnail) ;
        mImageView.setImageBitmap(getBitmapFromVideo(-1));
        mVideoView.setFocusable(false);
        mVideoView.requestFocus();
        mVideoView.start();
        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                // 这个被调用就会闪一下,何故会多次调用?mVideoView.resume() 方法有问题
//                D.i("slack","setOnPreparedListener...");
                mp.setLooping(true);

            }
        });

    }

    ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//            D.i("slack",position + ", " + positionOffset + ", " + positionOffsetPixels);
            // TODO: 2016/10/12  最右边 右滑,暂时这样处理
            if(position == 1 || (position == 2 && positionOffset == 0)){
                mImageView.setVisibility(View.VISIBLE);
            }

        }

        @Override
        public void onPageSelected(int position) {
            mCurrentPosition = position;
//            D.i("slack", "onPageSelected position: " + position );

        }

        @Override
        public void onPageScrollStateChanged(int state) {
//            D.i("slack", "onPageScrollStateChanged state: " + state );
            if(state == 0 && mCurrentPosition == 2){
                mImageView.setVisibility(View.GONE);
            }
        }
    };


    private Bitmap getBitmapFromVideo(long timeUs){
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        mmr.setDataSource(this, mUri);
        return mmr.getFrameAtTime(timeUs);
    }

    // TODO: 2016/10/11 这样 判断点击点坐标,maybe some problem
    View.OnTouchListener GifTouch = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP && isPointValid(event.getX(), event.getY())) {
                if (mIsPreInstallOK) {
                    startNewActivity(HomeActivity.class, true);
                } else {
                    showProgressDialog(getString(R.string.pre_installing));
                }
            }
            return true;
        }
    };
    
    private boolean isPointValid(float x, float y) {

//        D.i("slack", x + " - " + y);
        return x > getPx(R.dimen.common_measure_106dp) &&
                x < getPx(R.dimen.common_measure_252dp) &&
                y > getPx(R.dimen.common_measure_538dp) &&
                y < getPx(R.dimen.common_measure_610dp);
    }

    private int getPx(int id){
        return getResources().getDimensionPixelSize(id);
    }

    // 动画
    ViewPager.PageTransformer pageTransformer = new ViewPager.PageTransformer() {
        private final float MIN_SCALE = 0.85f;
        private final float MIN_ALPHA = 0.5f;

        @Override
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
            int pageHeight = view.getHeight();

            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);

            } else if (position <= 1) { // [-1,1]
                // Modify the default slide transition to shrink the page as well
                float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
                float vertMargin = pageHeight * (1 - scaleFactor) / 2;
                float horzMargin = pageWidth * (1 - scaleFactor) / 2;
                if (position < 0) {
                    view.setTranslationX(horzMargin - vertMargin / 2);
                } else {
                    view.setTranslationX(-horzMargin + vertMargin / 2);
                }

                // Scale the page down (between MIN_SCALE and 1)
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

                // Fade the page relative to its size.
                view.setAlpha(MIN_ALPHA +
                        (scaleFactor - MIN_SCALE) /
                                (1 - MIN_SCALE) * (1 - MIN_ALPHA));

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    };





版权声明:本文为博主原创文章,未经博主允许不得转载。

Android视频播放之ViewPager+VideoView

由于项目需求,项目主页面有很多个page页面,每个page页面中都有一个VideoView用于播放视频,写次demo用来练手。源码下载地址1、上效果图: 由于4个page页面的内容一样,所以看起来不...
  • xingpidong
  • xingpidong
  • 2016年10月26日 12:47
  • 3382

使用VIEWPAGER+SURFACEVIEW实现视频的循环滑动播放(一)

本文还是使用VIERPAGER来做视频切换。
  • yangchengtest
  • yangchengtest
  • 2017年02月19日 23:22
  • 1110

Android ViewPager使用详解,加载几个简单布局案例+代码

MainActivity代码如下: package com.example.viewpage; import android.support.v4.view.ViewPager; import a...
  • ITzhongzi
  • ITzhongzi
  • 2016年07月05日 11:39
  • 2991

Android 播放视频(四)VideoView全屏视频播放

Android 播放视频(四)VideoView全屏视频播放在教程(二)中讲述了VideoView如何播放视频,我们就总会产生一个需求,如何让VidoView进行全屏播放呢?当手机旋转进入横屏的时候让...
  • kingroc
  • kingroc
  • 2016年04月09日 23:56
  • 10578

android 启动页VideoView 播放本地视频短暂黑屏解决

在许多应用中,都加入了播放视频,有的在登录页,有的在启动页,今天就试试在启动页播放本地视频。 1,重写VideoView      由于 视频的尺寸问题导致VideoView 播放视频的时候不能全...
  • dhl_1986
  • dhl_1986
  • 2018年01月15日 15:03
  • 107

android 视频 无缝切换 无缝播放 surfaceview

android 视频 无缝切换 无缝播放 surfaceview最近做一个app,其中有一个控件要不断的播放视频,切换视频,然后遇到每次切换视频都会黑屏一会。 baidu,google没有找到有效的...
  • wenxiang423
  • wenxiang423
  • 2016年01月04日 15:03
  • 5586

Android 使用VDPlayerSDK组件实现播放视频(二)

在上一篇Android 使用VDPlayerSDK组件实现播放视频(一)中介绍了项目的导入,简单的介绍了项目如何导入运行,其实参考作者的demo,就可以简单的制作出一个视频播放器出来。我在这再啰嗦一下...
  • CutelittleBo
  • CutelittleBo
  • 2016年04月20日 12:57
  • 1853

【Android 多媒体开发】 MediaPlayer 网络视频播放器

.....
  • han1202012
  • han1202012
  • 2014年09月11日 11:19
  • 6120

Android客户端首次启动时的引导界面(viewpager)

刚做完一个比赛项目,来写点以后能用着的东西–Android客户端的首次启动页面,而且这个以后复用的几率很大,也不怎么修改,特留下为以后准备,同时为初学者提供一个帮助。 实现思路是:用SharedPr...
  • u013592964
  • u013592964
  • 2016年03月02日 23:18
  • 5564

Android学习之界面篇(六)ViewPager学习与Android引导界面的实现

ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view。ViewPager类直接继承了ViewGroup类,所以他是一个容器类,可以在其中添加其他的类    Vi...
  • icarus_wang
  • icarus_wang
  • 2016年04月30日 23:36
  • 981
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android之ViewPager+VideoView引导界面
举报原因:
原因补充:

(最多只允许输入30个字)