博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手把手教你实现慕课网导航效果(二)——编码实现
阅读量:6925 次
发布时间:2019-06-27

本文共 10114 字,大约阅读时间需要 33 分钟。

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

前言

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

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

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

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

imooc_guide.gif

正文

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);    }}

运行效果:

imooc_guide2.gif

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
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
fragments; public GuideFragmentPagerAdapter(FragmentManager fm,List
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的基本使用。

参考资料:

QQ20160303-0%402x.png

VideoView继承自,并实现了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                   +"\n2:"+uri2                   +"\n3:"+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;    }

运行效果:

imooc_guide3.gif

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

这里我们继承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);

运行效果:

imooc_guide5.gif

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

,并取得了40+个推荐以及首页推荐的成绩。欢迎各位支持推荐。

androidQQ20160622-0.png

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

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

欢迎交流讨论。

联系邮箱

你可能感兴趣的文章
PHP7和HHVM的性能之争
查看>>
我的友情链接
查看>>
【Visual C++】游戏开发四十八 浅墨DirectX教程十六 三维地形系统的实现
查看>>
程序的流程控制(C++)
查看>>
C++应用程序性能优化(五)——操作系统的内存管理
查看>>
嵌入式 Linux C语言(十)——静态库函数和动态库函数
查看>>
LVS之VS/DR搭建web集群实战!!!
查看>>
Java基础学习总结(20)——基础语法
查看>>
大型网站技术架构(四)网站的高性能架构
查看>>
jquery 刮奖插件
查看>>
es6--export default
查看>>
Java JNI 调用C++ API及中文编码问题
查看>>
Springmvc的开发流程--附带实例
查看>>
Java23中设计模式(Design Patterns)详解
查看>>
Java基础学习总结(3)——抽象类
查看>>
win7还未用熟 已经win10系统的身影了
查看>>
c#中的internal关键字
查看>>
Redis未授权访问之反弹shell
查看>>
C#中使用split分割字符串的几种方法
查看>>
使用Nginx如何配置Tomcat访问日志记录真实IP
查看>>