经过上一篇对慕课网导航效果的分析和验证,今天我们就来编码实现这一效果。还没有看过上一篇文章的同学,建议先看看手把手教你实现慕课网引导页效果(一)——分析验证。
通过本篇文章,我们可以学习到:
在编码之前,先回顾下慕课网的导航效果。
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来实现。
一般有三个步骤:
在这里,我们只需要创建一种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();
}
}
}
参考资料:
VideoView官网文档
Android--使用VideoView播放视频
VideoView继承自SurfaceView,并实现了MediaPlayerControl接口。用于播放视频文件。
几个主要的方法:
下面继续我们的慕课网视频引导效果的编码:
@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;
}
运行效果:
看运行效果,发现一个问题,视频的比例和手机的比例不一致导致右边出现蓝色长条。
这里我们继承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);
运行效果:
好,慕课网引导效果的编码实现就到这。如果喜欢,请推荐一下。谢谢。
本文是由JohnTsai原创。著作权由本人保留。
如需转载,请在显著位置注明出处。
欢迎交流讨论。