手把手教你炫酷慕课网视频启动导航的完美实现

来源:互联网 发布:手机绿色上网软件 编辑:程序博客网 时间:2024/06/05 05:59
看了慕课网的视频启动导航真心感觉不错,然后呢试着去做了个一模一样的效果,个人感觉效果还是不错的。 

先来看效果:




整体感觉效果还是非常不错的吧。

实现思路

看上面那个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,案例到此结束,大家有疑问可以留言~~

越努力,越幸运!!!


1 0
原创粉丝点击