zoukankan      html  css  js  c++  java
  • 手把手教你实现慕课网导航效果(二)——编码实现

    手把手教你实现慕课网导航效果(二)——编码实现

    前言

    经过上一篇对慕课网导航效果的分析和验证,今天我们就来编码实现这一效果。还没有看过上一篇文章的同学,建议先看看手把手教你实现慕课网引导页效果(一)——分析验证

    通过本篇文章,我们可以学习到:

    • 1.ViewPager+Fragment+FragmentPagerAdapter实现滑动导航页面
    • 2.VideoView(播放视频)的基本使用
    • 3.Activity转间动画

    在编码之前,先回顾下慕课网的导航效果。

    正文

    1.首先,我们先实现显示Logo的Activity(简称MainActivity),这个比较简单。看上面的GIF图,MainActivity显示一会时间后向左滑动消失,GuideActivity从右边滑动出来。那就讲讲其中的Activity转间动画(Transition animation)。

    一般使用下面的方式来实现:

    public void overridePendingTransition (int enterAnim, int exitAnim)
    //通常我们一般在startActivity(Intent)或finish()方法中调用此方法
    //其中enterAnim表示新Activity的进入动画,exitAnim表示旧Activity的退出动画
    
    //从Android4.1后,可以通过ActivityOptions将转间动画作为Bundle传入startActivity(Activity,Bundle)来实现
    
    

    来看代码实现:

    public class MainActivity extends AppCompatActivity {
    
        private Handler mHandler = new Handler();
        private Context mContext;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = this;
            //使用handler定时跳转到GuideActivity
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Intent intent = new Intent(mContext,GuideActivity.class);
                    //设置跳转动画
                    //第一种方式实现
                    startActivity(new Intent(mContext,GuideActivity.class));
                    finish();
                    overridePendingTransition(R.anim.slide_in_right,R.anim.slide_out_left);
                    
                    //第二种方式实现
    //                ActivityOptionsCompat optionsCompat =
    //                        ActivityOptionsCompat.makeCustomAnimation(mContext,R.anim.slide_in_right,
    //                                R.anim.slide_out_left);
    //                ActivityCompat.startActivity(MainActivity.this,intent,optionsCompat.toBundle());
    //                startActivity(new Intent(mContext,GuideActivity.class));
    //                finish();
                }
            }, 500);
    
        }
    }
    
    

    运行效果:

    2.接下来,实现滑动导航效果。相信现在讲这个的文章非常多,今天就当再复习一遍。呵呵,温故而知新。
    我们使用ViewPager+Fragment+FragmentPagerAdapter来实现。

    一般有三个步骤:

    • 1.实现Fragment的子类
    • 2.实现FragmentPagerAdapter适配器类
    • 3.将第2步生成的Adapter设置为ViewPager的适配器,并使用addOnPageChangeListener方法对ViewPager的Page更改的事件进行监听来实现标识第几页的功能。

    在这里,我们只需要创建一种Fragment即可。通过index参数来设置显示不同的图片和播放不同的视频。

    下面是GuideFragment的代码:

    /**
     * Created by JohnTsai on 16/3/3.
     */
    public class GuideFragment extends Fragment {
        public static String TAG = GuideFragment.class.getSimpleName();
        public static String KEY = "index";
    
        private VideoView mVideoView;
        private ImageView mImageView;
    
        private int index;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View guideView = inflater.inflate(R.layout.fragment_guide,container,false);
    
            mVideoView = (VideoView) guideView.findViewById(R.id.videoView);
            mImageView = (ImageView) guideView.findViewById(R.id.wordView);
    
            switch (index){
                case 0:
                    mImageView.setImageResource(R.mipmap.guide_1);
                    break;
                case 1:
                    mImageView.setImageResource(R.mipmap.guide_2);
                    break;
                case 2:
                    mImageView.setImageResource(R.mipmap.guide_3);
                    break;
            }
            Log.d(TAG,"onCreateView");
            return guideView;
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Bundle bundle = getArguments();
            index = bundle.getInt(KEY);
    
            Log.d(TAG,"onCreate");
        }
    
        public static GuideFragment newInstance(int index) {
    
            Bundle args = new Bundle();
            args.putInt(KEY, index);
    
            GuideFragment fragment = new GuideFragment();
            fragment.setArguments(args);
            return fragment;
        }
    }
    
    

    以及GuideActivity的代码

    /**
     * Created by JohnTsai on 16/3/3.
     */
    public class GuideActivity extends AppCompatActivity{
    
        private ImageView mDotOne,mDotTwo,mDotThree;
        private LinearLayout mLayoutBtn;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_guide);
    
            //初始化控件
            ViewPager mViewPager = (ViewPager) findViewById(R.id.viewPager);
            mDotOne = (ImageView) findViewById(R.id.guide_dot1);
            mDotTwo = (ImageView) findViewById(R.id.guide_dot2);
            mDotThree = (ImageView) findViewById(R.id.guide_dot3);
            mLayoutBtn = (LinearLayout) findViewById(R.id.btn_layout);
    
            GuideFragment guideFragment1 = GuideFragment.newInstance(0);
            GuideFragment guideFragment2 = GuideFragment.newInstance(1);
            GuideFragment guideFragment3 = GuideFragment.newInstance(2);
    
            List<? extends Fragment> mFragmentList = Arrays.asList(guideFragment1, guideFragment2, guideFragment3);
            GuideFragmentPagerAdapter mAdapter = new GuideFragmentPagerAdapter(getSupportFragmentManager(), mFragmentList);
            mViewPager.setAdapter(mAdapter);
    
            //设置小圆点
            mDotOne.setImageResource(R.mipmap.guide_dot_checked);
            mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                }
    
                @Override
                public void onPageSelected(int position) {
                    mDotOne.setImageResource(R.mipmap.guide_dot_normal);
                    mDotTwo.setImageResource(R.mipmap.guide_dot_normal);
                    mDotThree.setImageResource(R.mipmap.guide_dot_normal);
                    switch (position) {
                        case 0:
                            mDotOne.setImageResource(R.mipmap.guide_dot_checked);
                            break;
                        case 1:
                            mDotTwo.setImageResource(R.mipmap.guide_dot_checked);
                            break;
                        case 2:
                            mDotThree.setImageResource(R.mipmap.guide_dot_checked);
                            break;
                    }
                    //设置当滑动到最后一页时,显示两个按钮
                    mLayoutBtn.setVisibility(position==2? View.VISIBLE:View.GONE);
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    
        public static class GuideFragmentPagerAdapter extends FragmentPagerAdapter{
    
            private List <? extends Fragment> fragments;
    
            public GuideFragmentPagerAdapter(FragmentManager fm,List<? extends Fragment> fragments) {
                super(fm);
                this.fragments = fragments;
            }
    
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }
    
            @Override
            public int getCount() {
                return fragments.size();
            }
        }
    }
    
    
    1. 最后我们学习VideoView的基本使用。

    参考资料:

    VideoView官网文档

    Android--使用VideoView播放视频

    VideoView继承自SurfaceView,并实现了MediaPlayerControl接口。用于播放视频文件。

    几个主要的方法:

    • void setVideoPath(String path):以文件路径的方式设置VideoView播放的视频源。
    • void setVideoURI(Uri uri):以Uri的方式设置VideoView播放的视频源,可以是网络Uri或本地Uri。
    • void start():开始播放。
    • void stopPlayback():停止播放。
    • setMediaController(MediaController controller):设置MediaController控制器。
    • setOnCompletionListener(MediaPlayer.onCompletionListener l):监听播放完成的事件。
    • setOnErrorListener(MediaPlayer.OnErrorListener l):监听播放发生错误时候的事件。
    • setOnPreparedListener(MediaPlayer.OnPreparedListener l)::监听视频装载完成的事件。

    下面继续我们的慕课网视频引导效果的编码:

     @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View guideView = inflater.inflate(R.layout.fragment_guide, container, false);
    
            mVideoView = (VideoView) guideView.findViewById(R.id.videoView);
    
            //获取放置在raw文件夹得视频的Uri
            Uri uri1 =Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.guide_1);
            Uri uri2 =Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.guide_2);
            Uri uri3 =Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.guide_3);
    
            Log.d(TAG,"1:"+uri1
                       +"
    2:"+uri2
                       +"
    3:"+uri3);
    
            mImageView = (ImageView) guideView.findViewById(R.id.wordView);
    
            switch (index){
                case 0:
                    mImageView.setImageResource(R.mipmap.guide_1);
                    mVideoView.setVideoURI(uri1);
                    break;
                case 1:
                    mImageView.setImageResource(R.mipmap.guide_2);
                    mVideoView.setVideoURI(uri2);
                    break;
                case 2:
                    mImageView.setImageResource(R.mipmap.guide_3);
                    mVideoView.setVideoURI(uri3);
                    break;
            }
            mVideoView.start();
            //对VideoView的完成播放事件进行监听,完成后再次播放以达到循环播放的效果
            mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mVideoView.start();
                }
            });
            Log.d(TAG,"onCreateView");
            return guideView;
        }
    
    

    运行效果:

    看运行效果,发现一个问题,视频的比例和手机的比例不一致导致右边出现蓝色长条。

    这里我们继承VideoView来自定义设置它的宽和高来解决这个问题:

    代码如下:

    /**
     * Created by JohnTsai on 16/3/3.
     */
    public class CustomWidthHeightVideoView extends VideoView{
        private int mWidth = 0;
        private int mHeight = 0;
    
        public CustomWidthHeightVideoView(Context context) {
            super(context);
        }
    
        public CustomWidthHeightVideoView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomWidthHeightVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public void setWidthHeight(int width,int height){
            mWidth = width;
            mHeight = height;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if(mWidth>0&&mHeight>0)
                setMeasuredDimension(mWidth,mHeight);
            else
                super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        }
    }
    
    

    在onMeasure方法中,将我们设置的宽和高通过setMeasuredDimension来自定义VideoView的宽和高。

     //设置全屏播放
            DisplayMetrics metrics = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
            mVideoView.setWidthHeight(metrics.widthPixels,metrics.heightPixels);
    
    

    运行效果:

    好,慕课网引导效果的编码实现就到这。如果喜欢,请推荐一下。谢谢。

    本文同时发表于慕课网手记频道,并取得了40+个推荐以及首页推荐的成绩。欢迎各位支持推荐。

    本文是由JohnTsai原创。著作权由本人保留。

    如需转载,请在显著位置注明出处。

    欢迎交流讨论。

    联系邮箱JohnTsai.work@gmail.com

  • 相关阅读:
    Relativity 01: Physical Meaning of Geometrical Propositions
    Algo 2: Asymptotic Order of Growth
    CShop Project : BeanUtils工具的使用
    137 __getattribute__
    134 isinstance和issubclass
    135 反射(hasattr和getattr和setattr和delattr)
    133 面向对象进阶实战之选课系统
    132 面向对象进阶小结
    131 类和对象的绑定方法及非绑定方法
    130 类的property特性
  • 原文地址:https://www.cnblogs.com/JohnTsai/p/5239569.html
Copyright © 2011-2022 走看看