手把手教你炫酷慕课网视频启动导航的完美实现
2016-09-27 13:22
316 查看
看了慕课网的视频启动导航真心感觉不错,然后呢试着去做了个一模一样的效果,个人感觉效果还是不错的。
先来看效果:
整体感觉效果还是非常不错的吧。
看上面那个GIF图,分析可知。首先是一个显示慕课网LOGO的Activity,然后跳转到了今天我们要讲的引导效果的Activity
根据它滑动的效果,可猜测是由ViewPager实现的。
ViewPager中有三个播放着动画或者视频的Fragment。
底部有标识滑动到哪一页的小圆点。
当滑动到第三页时,出现登录、注册按钮。
打开慕课网App的引导页面,以为是用gif图片做的,后来发现每个引导页面都是加载的一段视频。 既然我们知道每个页面都是视频的话,那么就很好做了有木有,既然是几个引导页我就想到了轮播图那就使用viewPager来实现是比较轻松的,每个视频用Fragment这样的话复用率比较高,所以就选择用FragmentPagerAdapter,然后播放视频呢本来想用Vitamio然后呢发现videoView来实现比较简单,所以果断使用,然后还加上登录注册和首页,这里为了简单直观直接使用webView加载的效果是不是特别的炫,如果是第一次也会去慕课网那样的提示页,是不是感觉非常棒。
在Android中,我们有三种方式来实现视频的播放:
1、使用其自带的播放器。指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。
2、使用VideoView来播放。在布局文件中使用VideoView结合MediaController来实现对其控制。
3、使用MediaPlayer类和SurfaceView来实现,这种方式很灵活。
Android支持播放网络上的视频。在播放网络上的视频时,牵涉到视频流的传输,往往有两种协议,
一种是HTTP,一种是RTSP。这
两种协议最大的不同是,HTTP协议,不支持实时流媒体的播放,而RTSP协议就支持。
Android中自带的播放器,以及VideoView等都支持上述两种协议,因此,可以直接播放网络上的视频,唯一不同的就是URI。
VideoView播放视频的步骤:
1、在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件
2、调用VideoView的如下两个方法来加载指定的视频
setVidePath(String path):加载path文件代表的视频
setVideoURI(Uri uri):加载uri所对应的视频
3、调用VideoView的start()、stop()、psuse()方法来控制视频的播放
VideoView使用注意:
1.先把要播放的视频放到res/raw目录下,注明我这里要播放的是Android项目中的资源文件,而不是访问SD卡播放视频。
2.视频格式必须是Android支持的格式(3gp,mp4,wmv),据说swf不支持,暂未试过。并且视频文件命名不能有大写字母,必须是小写字母、数字或下划线。
3.布局文件中添加VideoView组件
4.创建个String类型对象保存uri
5.调用VideoView的setVideoURI方法设置URI,参数为上面的uri
6.调用start()方法播放。
准备工作
1 .准备3个mp4格式的启动页视频
2.准备2个图片(白点)
3.准备几个webView需要加载的URL
不多说看代码:
先来布局:(导航页)
其实不封装也是差不多的,代码很简单我们来看下Fragment的布局:
接下来我们来看Fragment里面的代码,也是很简单:
上面这段代码无非就是为了公用一个Fragment所以无非就是播放Raw文件下的不同视频而已。好了我们来看下导航的代码:
上面这代码无非就是把fragment适配到viewPager里面,并且根据选择到第几页来控制下面的白点,当到第三页时让登录注册按钮显示,和点击按钮执行相关的操作。
为了让效果更加好点,点击登录注册用的web
View加载,顺便对webView进行了简单的封装。
ok,案例到此结束,大家有疑问可以留言~~
越努力,越幸运!!!
先来看效果:
整体感觉效果还是非常不错的吧。
实现思路
看上面那个GIF图,分析可知。首先是一个显示慕课网LOGO的Activity,然后跳转到了今天我们要讲的引导效果的Activity根据它滑动的效果,可猜测是由ViewPager实现的。
ViewPager中有三个播放着动画或者视频的Fragment。
底部有标识滑动到哪一页的小圆点。
当滑动到第三页时,出现登录、注册按钮。
实现的技术分析:
打开慕课网App的引导页面,以为是用gif图片做的,后来发现每个引导页面都是加载的一段视频。 既然我们知道每个页面都是视频的话,那么就很好做了有木有,既然是几个引导页我就想到了轮播图那就使用viewPager来实现是比较轻松的,每个视频用Fragment这样的话复用率比较高,所以就选择用FragmentPagerAdapter,然后播放视频呢本来想用Vitamio然后呢发现videoView来实现比较简单,所以果断使用,然后还加上登录注册和首页,这里为了简单直观直接使用webView加载的效果是不是特别的炫,如果是第一次也会去慕课网那样的提示页,是不是感觉非常棒。
Android三种播放视频的方式
在Android中,我们有三种方式来实现视频的播放:1、使用其自带的播放器。指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。
2、使用VideoView来播放。在布局文件中使用VideoView结合MediaController来实现对其控制。
3、使用MediaPlayer类和SurfaceView来实现,这种方式很灵活。
videoView的使用
Android支持播放网络上的视频。在播放网络上的视频时,牵涉到视频流的传输,往往有两种协议,一种是HTTP,一种是RTSP。这
两种协议最大的不同是,HTTP协议,不支持实时流媒体的播放,而RTSP协议就支持。
Android中自带的播放器,以及VideoView等都支持上述两种协议,因此,可以直接播放网络上的视频,唯一不同的就是URI。
VideoView播放视频的步骤:
1、在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件
2、调用VideoView的如下两个方法来加载指定的视频
setVidePath(String path):加载path文件代表的视频
setVideoURI(Uri uri):加载uri所对应的视频
3、调用VideoView的start()、stop()、psuse()方法来控制视频的播放
VideoView使用注意:
1.先把要播放的视频放到res/raw目录下,注明我这里要播放的是Android项目中的资源文件,而不是访问SD卡播放视频。
2.视频格式必须是Android支持的格式(3gp,mp4,wmv),据说swf不支持,暂未试过。并且视频文件命名不能有大写字母,必须是小写字母、数字或下划线。
3.布局文件中添加VideoView组件
4.创建个String类型对象保存uri
5.调用VideoView的setVideoURI方法设置URI,参数为上面的uri
6.调用start()方法播放。
准备工作
1 .准备3个mp4格式的启动页视频
2.准备2个图片(白点)
3.准备几个webView需要加载的URL
代码解说
不多说看代码: 先来布局:(导航页)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:showIn="@layout/activity_main" tools:context=".MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/button_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="50dp" android:gravity="center_horizontal" android:orientation="horizontal" android:visibility="gone"> <TextView android:id="@+id/login" android:layout_width="140dp" android:layout_height="48dp" android:background="@drawable/guide_login_btn_bg" android:gravity="center" android:text="登录/注册" android:textColor="@color/black_000000" android:textSize="18dp" /> <TextView android:id="@+id/enter" android:layout_width="140dp" android:layout_height="48dp" android:layout_marginLeft="20dp" android:background="@drawable/guide_enter_btn_bg" android:gravity="center" android:text="立即体验" android:textColor="@color/white_66FFFFFF" android:textSize="18sp" /> </LinearLayout> <LinearLayout android:id="@+id/dot_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:layout_marginBottom="10dp" android:orientation="horizontal" /> </RelativeLayout>然后ViewPager里面使用的是Fragment里面使用的是VideoView来播放视频。所以自定义videoView便于视频的播放管理,看代码:
package com.richerpay.videoview.moocguide.view; import android.annotation.TargetApi; import android.content.Context; import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.util.AttributeSet; import android.widget.VideoView; @TargetApi(Build.VERSION_CODES.LOLLIPOP) public class MCVideoView extends VideoView { public MCVideoView(Context context) { super(context,null); } public MCVideoView(Context context, AttributeSet attrs) { super(context, attrs,0); } public MCVideoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr, 0); } public MCVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } public void playVideo(Context context, Uri paramUri) { if (paramUri == null) throw new IllegalArgumentException("Uri can not be null"); setVideoURI(paramUri); start(); setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setLooping(true); } }); setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { return true; } }); } }
其实不封装也是差不多的,代码很简单我们来看下Fragment的布局:
<?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" android:orientation="vertical"> <com.richerpay.videoview.moocguide.view.MCVideoView android:id="@+id/videoview" android:layout_width="match_parent" android:layout_height="match_parent" /> <View android:id="@+id/guide_bg" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
接下来我们来看Fragment里面的代码,也是很简单:
package com.richerpay.videoview.moocguide.fragmnet; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.richerpay.videoview.moocguide.R; import com.richerpay.videoview.moocguide.view.MCVideoView; public class GuideFragment extends Fragment { private View mBgView; private Context mContext; private MCVideoView mVideoView; @Override public void onAttach(Context context) { super.onAttach(context); this.mContext=context; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View localView = inflater.inflate(R.layout.guide_item_layout, null); initView(localView); return localView; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initData(); } private void initView(View localView) { mVideoView = ((MCVideoView)localView.findViewById(R.id.videoview)); mBgView = localView.findViewById(R.id.guide_bg); } private void initData() { Bundle localBundle = getArguments(); int i = 0; int j = 0; int k = 0; if ((localBundle != null) && (localBundle.containsKey("index"))) i = localBundle.getInt("index"); try { String str = "guide_" + i; j = R.raw.class.getDeclaredField(str).getInt(this); int l = R.mipmap.class.getDeclaredField(str).getInt(this); k = l; if (j != 0) this.mVideoView.playVideo(mContext, Uri.parse("android.resource://" + this.mContext.getPackageName() + "/" + j)); if (k != 0) this.mBgView.setBackgroundResource(k); return; } catch (Exception localException) { } } @Override public void onDestroy() { super.onDestroy(); if (this.mVideoView == null) return; this.mVideoView.stopPlayback(); } }
上面这段代码无非就是为了公用一个Fragment所以无非就是播放Raw文件下的不同视频而已。好了我们来看下导航的代码:
package com.richerpay.videoview.moocguide; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.richerpay.videoview.moocguide.fragmnet.GuideFragment; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private ViewPager viewpager; private FragmentPagerAdapter mAdapter; private List<Fragment> mFragments; private ImageView[] images; private GuideFragment mTab01; private GuideFragment mTab02; private GuideFragment mTab03; private TextView login, enter; private LinearLayout button_layout, dot_layout; private ObjectAnimator mAnim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); setSelect(0); initDot(0); } private void initEvent() { login.setOnClickListener(this); enter.setOnClickListener(this); } private void initView() { login = (TextView) findViewById(R.id.login); enter = (TextView) findViewById(R.id.enter); button_layout = (LinearLayout) findViewById(R.id.button_layout); dot_layout = (LinearLayout) findViewById(R.id.dot_layout); viewpager = (ViewPager) findViewById(R.id.id_viewpager); mFragments = new ArrayList<Fragment>(); Bundle bundel = new Bundle(); mTab01 = new GuideFragment(); bundel.putInt("index", 1); mTab01.setArguments(bundel); mTab02 = new GuideFragment(); Bundle bunde2 = new Bundle(); bunde2.putInt("index", 2); mTab02.setArguments(bunde2); mTab03 = new GuideFragment(); Bundle bunde3 = new Bundle(); bunde3.putInt("index", 3); mTab03.setArguments(bunde3); mFragments.add(mTab01); mFragments.add(mTab02); mFragments.add(mTab03); mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public int getCount() { // TODO Auto-generated method stub return mFragments.size(); } @Override public Fragment getItem(int arg0) { // TODO Auto-generated method stub return mFragments.get(arg0); } }; viewpager.setAdapter(mAdapter); viewpager.setOnPageChangeListener(new android.support.v4.view.ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int pos) { int currentItem = viewpager.getCurrentItem(); setTab(currentItem); initDot(pos); images[pos].setEnabled(true); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); } private void setSelect(int i) { setTab(i); viewpager.setCurrentItem(i); } private void setTab(int i) { switch (i) { case 0: button_layout.setVisibility(View.GONE); fadeInAnim(button_layout); break; case 1: button_layout.setVisibility(View.GONE); fadeInAnim(button_layout); break; case 2: button_layout.setVisibility(View.VISIBLE); initEvent(); break; default: break; } } @Override public void onClick(View v) { if (v.getId() == R.id.login) { goLoginActivity(); } if (v.getId() == R.id.enter) { if (Constant.isFrist) goIndexActivity(); else goInitActivity(); } } private void goInitActivity() { startActivity(new Intent(this, InitActivity.class)); finish(); } private void goIndexActivity() { startActivity(new Intent(this, IndexActivity.class)); finish(); } private void goLoginActivity() { startActivity(new Intent(this, LoginActivity.class)); finish(); } private void fadeInAnim(View paramView) { if (Build.VERSION.SDK_INT < 11) return; float[] arrayOfFloat = new float[2]; arrayOfFloat[0] = 0.0F; arrayOfFloat[1] = 1.0F; mAnim = ObjectAnimator.ofFloat(paramView, "alpha", arrayOfFloat).setDuration(1000L); AnimatorSet localAnimatorSet = new AnimatorSet(); localAnimatorSet.play(mAnim); localAnimatorSet.start(); } /** *初始化下面的点 */ private void initDot(int select) { //设置点的个数为fragment的数量 images = new ImageView[mFragments.size()]; //先移除所有的点 dot_layout.removeAllViews(); for (int i = 0; i < mFragments.size(); i++) { ImageView localImageView = new ImageView(this); LinearLayout.LayoutParams localLayoutParams = new LinearLayout.LayoutParams(-2, -2); //左边距为30 localLayoutParams.leftMargin = 30; localImageView.setLayoutParams(localLayoutParams); localImageView.setImageResource(R.drawable.dot_bg); if (i == select) //如果选中则图片变为白点 localImageView.setEnabled(true); else //否者就为暗一点的白点 localImageView.setEnabled(false); images[i] = localImageView; dot_layout.addView(localImageView); } } }
上面这代码无非就是把fragment适配到viewPager里面,并且根据选择到第几页来控制下面的白点,当到第三页时让登录注册按钮显示,和点击按钮执行相关的操作。
为了让效果更加好点,点击登录注册用的web
package com.richerpay.videoview.moocguide.view; import android.content.Context; import android.graphics.Bitmap; import android.view.KeyEvent; import android.webkit.WebSettings; import android.webkit.WebSettings.RenderPriority; import android.webkit.WebSettings.ZoomDensity; import android.webkit.WebView; import android.webkit.WebViewClient; /** * 自定义WebView,长按图片获取图片url * */ public class CustomWebView extends WebView{ private Context context; public CustomWebView(Context context) { super(context); this.context = context; initSettings(); } private void initSettings() { // 初始化设置 WebSettings mSettings = this.getSettings(); mSettings.setJavaScriptEnabled(true);//开启javascript mSettings.setDomStorageEnabled(true);//开启DOM mSettings.setDefaultTextEncodingName("utf-8");//设置字符编码 //设置web页面 mSettings.setAllowFileAccess(true);//设置支持文件流 mSettings.setSupportZoom(true);// 支持缩放 mSettings.setBuiltInZoomControls(true);// 支持缩放 mSettings.setUseWideViewPort(true);// 调整到适合webview大小 mSettings.setLoadWithOverviewMode(true);// 调整到适合webview大小 mSettings.setDefaultZoom(ZoomDensity.FAR);// 屏幕自适应网页,如果没有这个,在低分辨率的手机上显示可能会异常 mSettings.setRenderPriority(RenderPriority.HIGH); //提高网页加载速度,暂时阻塞图片加载,然后网页加载好了,在进行加载图片 mSettings.setBlockNetworkImage(true); mSettings.setAppCacheEnabled(true);//开启缓存机制 setWebViewClient(new MyWebViewClient()); } private class MyWebViewClient extends WebViewClient { /** * 加载过程中 拦截加载的地址url * @param view * @param url 被拦截的url * @return */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return super.shouldOverrideUrlLoading(view, url); } /** * 页面加载过程中,加载资源回调的方法 * @param view * @param url */ @Override public void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); } /** * 页面加载完成回调的方法 * @param view * @param url */ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 关闭图片加载阻塞 view.getSettings().setBlockNetworkImage(false); } /** * 页面开始加载调用的方法 * @param view * @param url * @param favicon */ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); } @Override public void onScaleChanged(WebView view, float oldScale, float newScale) { super.onScaleChanged(view, oldScale, newScale); CustomWebView.this.requestFocus(); CustomWebView.this.requestFocusFromTouch(); } } @Override // 设置回退 // 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法 public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && this.canGoBack()) { this.goBack(); // goBack()表示返回WebView的上一页面 return true; } return super.onKeyDown(keyCode,event); } }
View加载,顺便对webView进行了简单的封装。
ok,案例到此结束,大家有疑问可以留言~~
越努力,越幸运!!!
相关文章推荐
- 手把手教你炫酷慕课网视频启动导航的完美实现
- 慕课网视频启动导航的炫酷简单完美实现
- 手把手教你实现慕课网导航效果(二)——编码实现
- ADSL拨号网络环境下实时视频广播的完美实现
- IOS实现视频动画效果的启动图
- VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 手把手教你TabLayout、ViewPager、Fragment实现顶部导航
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
- iOS纯Autolayout实现微信朋友圈和通讯录另附App启动页短视频效果
- 手把手实现用Cacti监控资源+完美监控MySQL等服务
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
- ADSL拨号网络环境下实时视频广播的完美实现
- 机器人视觉导航的OpenCV实现-视频演示
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
- jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
- Android集成讯飞SDK实现语音拨号、语音导航、语音启动应用