VR小项目(三)

来源:互联网 发布:sqlserver 大数据导入 编辑:程序博客网 时间:2024/05/17 02:40
VR小项目(三)



VR小项目(一)
VR小项目(二)
VR小项目(三)
17.打开上面上面创建好的VrVideoFragment并继承我们自己写的BaseFragment并实现他的两个方法
/** * Date:2017/3/18 * author:陈箫阳ChenXiaoYang * furction: */public class VrVideoFragment extends BaseFragment {    private RecyclerView recyclerView;    @Override    public RecyclerView.LayoutManager getLayoutManager() {        //VR视频使用GridView的样式,参数    1.上下文      2.决定一行几列        return new GridLayoutManager(getActivity(), 2);    }    //在这里我们要复写onViewCreated方法    @Override    public void onViewCreated(View view, Bundle savedInstanceState) {        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);        //从接口中拿到LayoutManager        RecyclerView.LayoutManager loaderManager = getLayoutManager();        //设置LayoutManager,让子类不用再设置        recyclerView.setLayoutManager(loaderManager);        //使用开源框架OKGO,加载网址        OkGo.get(ApiUrls.URL_Query)    }    @Override    protected RecyclerView.Adapter getAdapter() {        return null;    }}
在这里ApiUrls会报红,我们需要使用快捷键创建ApiUrls类用于存放网络数据,然后将Apiurls放入utli包中
/** * Date:2017/3/19 * author:陈箫阳ChenXiaoYang * furction: */public class ApiUrls {    public static String API_HOST = "api.youkes.com";    public static int API_PORT = 8081;    public static String URL_Query = "http://" + API_HOST + ":" + API_PORT + "/api/video/query";}
此时回到VrVideoFragment类 
在这里我们要使用JSON需要导入:com.alibaba:fastjson:1.2.29
步骤:按住control+alt+shift+s会弹出一个Project Structure点击所要添加的项目,点击Dependencies,点击+号,选择Library Dependency

.cacheKey(ApiUrls.URL_Query)//默认加载键.cacheMode(CacheMode.DEFAULT)//采用默认格式.execute(new StringCallback() {    //网络请求成功的回调    @Override    public void onSuccess(String s, Call call, Response response) {        try {            //创建原生的JSONObject来解析数据            JSONObject obj = new JSONObject(s);            String content = obj.getString("content");            //然后报解析的数据先放在Bean类,再放到集合里,这里我们用Gson,fastJson会更方便            List<VideoItem> videoItems = JSON.parseArray(content, VideoItem.class);            //给RecyclerView设置适配器,把数据集合传到适配器里            recyclerView.setAdapter(new VrVideoAdapter(videoItems));        } catch (JSONException e) {            e.printStackTrace();        }    }});
在这里List集合的VideoItem会报红,使用快捷键创建VideoItem类,VrVideoAdapter也会报红,使用快捷键创建VrVideoAdapter适配器类实现一个内部抽象方法然后在让他调用父类的方法
/** * Date:2017/3/19 * author:陈箫阳ChenXiaoYang * furction: */public class VideoItem {    public String vtype;    public String id;    public String key;    public String play;    public String title;    public String img;    public String url;    public String isbin;    public String t0;    public String t1;    public String t2;    public String userName;    public String userNick;    public String userPhoto;    public String vclass;    public int width;    public int height;    public float score0;    public long date;    public String _id;    public String userId;    public String[] tags;    public int cnt;    public String type;    public String videoChannelName;    public String videoChannelId;    public String text;    public String textSimple;    public String dateCnSimple;}
/** * Date:2017/3/17 * author:陈箫阳ChenXiaoYang * furction:VR视频模块RecyclerView所需适配器 */public class VrVideoAdapter extends BaseQuickAdapter<VideoItem> {    //通过构造方法,加载一个默认布局及获取传过来的数据    public VrVideoAdapter(List<VideoItem> videoItems) {        super(R.layout.vr_video_list_item, videoItems);    }    @Override    protected void convert(BaseViewHolder helper, VideoItem item) {    }}
在这里R.layout.vr_video_list_item会报红,使用快捷键创建vr_video_list_item布局文件,显示一些简单的布局,用到了一些颜色需要以下步骤
    1.打开res下的values包再打开colors布局文件添加一些颜色
<?xml version="1.0" encoding="utf-8"?><resources>    <color name="colorPrimary">#3F51B5</color>    <color name="colorPrimaryDark">#303F9F</color>    <color name="colorAccent">#FF4081</color>    <!--vr_video_list_item里自定义的颜色-->    <color name="white_light">#f2f2f2</color>    <color name="white">#fafafa</color>    <color name="gray_dark_blue">#5A6377</color>    <color name="gray_light">#efefef</color>    <color name="black">#ff000000</color>    <color name="gray_less_light">#666666</color>    <color name="gray">#777</color>    <color name="gray_dark">#383838</color>    <color name="green_light">#8e9ea4</color>    <color name="green">#34515c</color>    <color name="green_dark">#1e3e4a</color>    <color name="night_mask">#90000000</color>    <color name="gray_darker">#2b2b2b</color>    <color name="gray_lighter">#efefef</color>    <color name="gray_alpha_light">#90999999</color>    <color name="semitransparent_light">#20000000</color>    <color name="white_dark">#f3f3f3</color></resources>
    2.在drawable下创建select_button.xml布局文件
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true"          android:drawable="@color/white_light"></item>    <item android:drawable="@color/white"></item></selector>
回到VrVideoAdapter适配器类,
注意:这里特别要注意的是SimpleDateFormat

com.ibm.icu.text.SimpleDateFormatjava.text.SimpleDateFormat比较

  1.fomat()方法,前者比后者大一小时

  2.parse()方法,前者比后者小一小时

  3.当然 java.text.SimpleDateFormat得到的结果是正确的

com.ibm.icu.text.SimpleDateFormat是ICU4J中的一个类。ICU4J 是IBM的国际化开发组件ICU 的Java语言实现版本。为何会发生这种怪异现象,我也没搞清楚,初步猜测是因为ibm这个包的默认时区不同。所以大家用ICU这个SimpleDateFormat时应该注意导入是哪个包


//标签TextView的控件Idprivate int[] ids = {R.id.tag0, R.id.tag1, R.id.tag2};@Overrideprotected void convert(BaseViewHolder helper, VideoItem item) {    //设置Item的标题,从bean类里拿对象的数据,直接就可以根据控件ID设置进去,这是开源框架的便利    helper.setText(R.id.topic_init_title, item.title);    //设置Item的时间,使用simpleDateFormat(java的知识点),对时间数据进行格式化    helper.setText(R.id.date_text, new SimpleDateFormat("MM/DD/yyyy").format(item.date));    //根据控件ID获取到控件对象    ImageView topicImg = helper.getView(R.id.topic_init_img);    //使用开源框架,根据网址加载图片    Glide.with(helper.getConvertView().getContext())//获取上下文            .load(item.img)//网址            .into(topicImg);//ImageView控件对象    //从bean类里拿到标签    String[] tags = item.tags;    //根据标签的数量,做对应的循环操作,把标签设置到TextView文本里    for (int x = 0; x < tags.length; x++) {        //设置文本,参数  1 数组里的ID   2 要塞入的数据        helper.setText(ids[x], tags[x]);    }}
到此VR视屏的页面就制作好了
效果图

18.接下来就要编写VR视屏的点击事件了
首先在convert方法中获取item并设置点击事件
//B.获取到item容器的ID值,设置点击事件View view = helper.getView(R.id.video_layout);//使用设置标签的形式,以控件为容器,把数据放入其中,进行传递view.setTag(item);//设置点击事件view.setOnClickListener(listener);
在这里listener会报红,这时我们需要在convert方法外创建私有的listener点击事件
//B.点击事件的处理private View.OnClickListener listener = new View.OnClickListener() {    @Override    public void onClick(View v) {        //从控件里取出数据,进行强类型转换        VideoItem item = (VideoItem) v.getTag();        //创建Intent对象, 参数  1.上下文   2.类字节,显示播放详情类        Intent intent = new Intent(v.getContext(), VideoDeTailActivity.class);        //需要传递的数据,把数据放入Intent,进行传输        intent.putExtra("title", item.title);        intent.putExtra("img", item.img);        intent.putExtra("text", item.text);        intent.putExtra("play", item.play);        //获取上下文,开启Activity的跳转        v.getContext().startActivity(intent);    }};

19.在这里VideoDeTailActivity类会报红,因为还没有这个跳转的类,所以我们要使用快捷键创建VideoDeTailActivity类并创建activity_video_de_tail布局文件
首先编写布局文件

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             android:id="@+id/video_detail"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:background="@color/white">    <ScrollView        android:layout_width="fill_parent"        android:layout_height="fill_parent">        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:orientation="vertical">            <LinearLayout                android:id="@+id/control_bar"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:orientation="horizontal"                android:padding="2dip">                <TextView                    android:id="@+id/title_text"                    android:layout_width="fill_parent"                    android:layout_height="wrap_content"                    android:layout_margin="8dip"                    android:text=""                    android:textSize="16sp"/>            </LinearLayout>            <RelativeLayout                android:layout_width="match_parent"                android:layout_height="200dp"                android:layout_margin="4dp"                android:background="@color/gray_lighter"                android:orientation="horizontal">                <ImageView                    android:id="@+id/detail_img_view"                    android:layout_width="match_parent"                    android:layout_height="200dp"                    android:background="@color/black"                    android:clickable="true"                    android:scaleType="centerCrop"                    android:src="@mipmap/pictures_no"/>                <TextView                    android:id="@+id/video_type"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@color/semitransparent_light"                    android:padding="8dp"                    android:text="视频"                    android:textColor="@color/white"                    android:textStyle="bold"/>                <ImageButton                    android:id="@+id/play_link"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_centerHorizontal="true"                    android:layout_centerVertical="true"                    android:background="#22222222"                    android:contentDescription="播放语音"                    android:gravity="center"                    android:src="@drawable/mediacontroller_play_button"/>            </RelativeLayout>            <TextView                android:id="@+id/detail_text"                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:layout_margin="8dip"                android:textColor="@color/gray_less_light"                android:textSize="16sp"/>        </LinearLayout>    </ScrollView></FrameLayout>
在这里mediacontroller_play_button会报红,使用快捷键创建布局文件,在这里有一些图片
在drawable下创建mediacontroller_play_button.xml布局文件

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true" android:drawable="@mipmap/mediacontroller_play02"/>    <item android:drawable="@mipmap/mediacontroller_play01"/></selector>
20.回到VideoDeTailActivity类,接收跳转数据
public class VideoDeTailActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_video_de_tail);        init();    }    //初始化数据    private void init() {        //拿到传过来的Intent对象        final Intent intent = getIntent();        //从Intent对象里,根据键值,拿到我们所需要的数据        String title = intent.getStringExtra("title");        String img = intent.getStringExtra("img");        String text = intent.getStringExtra("text");        final String play = intent.getStringExtra("play");        //方别把拿到的数据放入对应的控件里,设置标题        TextView mTextView = (TextView) findViewById(R.id.title_text);        mTextView.setText(title);        //用Glide设置图片        ImageView ivImg = (ImageView) findViewById(R.id.detail_img_view);        Glide.with(this)//上下文                .load(img)//UI地址                .into(ivImg);//ImageView控件对象        //设置影片介绍文本        TextView tv_detail = (TextView) findViewById(R.id.detail_text);        tv_detail.setText(text);        //找到ImageButton控件对象,设置点击事件        findViewById(R.id.play_link).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent vrIntent = new Intent(VideoDeTailActivity.this, VideoPlayerActivity.class);                //使用Intent传输所要传的值                vrIntent.putExtra("play", play);                //开启界面                startActivity(vrIntent);            }        });    }}
在这里VideoPlayerActivity会报红因为没有这个跳转类,所以创建VideoPlayerActivity类并创建activity_video_player.xml布局文件
首先编写activity_video_player.xml  

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <com.google.vr.sdk.widgets.video.VrVideoView        android:id="@+id/vr_video"        android:layout_width="match_parent"        android:layout_height="250dp"/>    <android.support.v7.widget.AppCompatSeekBar        android:id="@+id/seek_bar"        android:layout_width="match_parent"        android:layout_height="wrap_content"    />    <TextView        android:id="@+id/tv_progress"        android:textSize="20dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>
VR视屏要导入VR资源包
打开gvr-android-sdk-master打开libraries

在Studio中导入
步骤:点击File<New<Improp module粘贴文件路径点击Finish

然后按住control+alt+shift+s会弹出一个Project Structure点击所要添加的项目,点击Dependencies,点击+号,选择Module Dependency

最后回到VideoPlayerActivity类获取跳转内容,并编写VR视屏界面
public class VideoPlayerActivity extends AppCompatActivity {    private VrVideoView vr_video;    private SeekBar seek_bar;    private TextView tv_progress;    private VideoLoadTask mVideoLoadTask;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_video_player);        //获取传过来的Intent        Intent intent = getIntent();        //从Intent里拿到我们的数据        String play = intent.getStringExtra("play");        //A.进行控件的初始化        vr_video = (VrVideoView) findViewById(R.id.vr_video);        seek_bar = (SeekBar) findViewById(R.id.seek_bar);        tv_progress = (TextView) findViewById(R.id.tv_progress);        //隐藏VR效果左下角的信息按钮显示        vr_video.setInfoButtonEnabled(false);        //切换VR的模式   参数:VrVideoView.DisplayMode.FULLSCREEN_STEREO:设备模式(手机横着放试试)VrVideoView.DisplayMode..FULLSCREEN_MONO手机模式        vr_video.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);        //D.对VR视频进行事件监听        vr_video.setEventListener(new MyEventListener());        //B.播放VR效果,只需执行异步任务即可        mVideoLoadTask = new VideoLoadTask();        mVideoLoadTask.execute(play);    }    //B.由于VR资源数据量大,获取需要时间,故把加载视频放到子线程中进行,主线程来显示,可以使用一个异步线程AsyncTask或EventBus技术完成.    //B.自定义一个类继承AsyncTask,只使用我们需要的方法.完成在子线程加载图片资源,在主线程显示    private class VideoLoadTask extends AsyncTask<String, Void, Void> {        //B.该方法在子线程运行,从本地文件中把资源加载到内存中        @Override        protected Void doInBackground(String... strings) {            //创建VrVideoView.Options对象,决定VR是普通的效果,还是立体效果            VrVideoView.Options options = new VrVideoView.Options();            //立体模式            options.inputType = VrVideoView.Options.TYPE_STEREO_OVER_UNDER;            //处理加载的视频格式            //FORMAT_DEFAULT:默认格式(SD卡或assets)            //FORMAT_HLS:流媒体数据格式(直播)            options.inputFormat = VrVideoView.Options.FORMAT_DEFAULT;            try {                //提示:视频加载的方法还做了把视频读取到内存中的操作,所以它有一个矛盾,调用该方法是放在主线程还是子线程(一般我们放在子线程)                //使用VR控件对象,从资产目录加载视频数据,显示效果 参数: 1.String对象 2.VrVideoView.Options对象,决定显示效果                //vr_video.loadVideoFromAsset(strings[0], options);//不要管他在爆红,就在子线程里执行                //使用VR控件对象,从网络加载视频数据,显示效果(要加网络权限)   参数:   1.视频网址,String对象                vr_video.loadVideo(Uri.parse(strings[0]), options);            } catch (IOException e) {                e.printStackTrace();            }            return null;        }    }    //C.因为VR很占用内存,所以当界面进入OnPause状态,暂停VR视图显示,进入OnResume状态,继续VR视图显示,进入OnDestroy状态,杀死VR,关闭异步任务    //当失去焦点时,回到    @Override    protected void onPause() {        super.onPause();        //暂停渲染和显示        vr_video.pauseRendering();    }    //当获取焦点时,回调    @Override    protected void onResume() {        super.onResume();        //继续渲染和显示        vr_video.resumeRendering();    }    //当Activity销毁时,回调    @Override    protected void onDestroy() {        super.onDestroy();        //关闭渲染视图,回调        vr_video.shutdown();        //在退出Activity时,如果异步任务没有取消,则取消        if (mVideoLoadTask != null) {            if (!mVideoLoadTask.isCancelled()) {                mVideoLoadTask.cancel(true);            }        }    }    //VR运行状态监听类,自定义一个类继承VrVideoEventListener,复写里面需要的方法    private class MyEventListener extends VrVideoEventListener {        //当VR视图加载成功的时候的回调,此时还未开始播放        @Override        public void onLoadSuccess() {            super.onLoadSuccess();            //获取视频的长度            long max = vr_video.getDuration();            //设置seekbar的进度最大值            seek_bar.setMax((int) max);        }        //当VR视图加载失败的时候回调的方法        @Override        public void onLoadError(String errorMessage) {            super.onLoadError(errorMessage);            Toast.makeText(VideoPlayerActivity.this, "播放失败", Toast.LENGTH_SHORT).show();        }        //当视频开始播放,每次进入下一帧的时候,回调这个方法(就是播放时,会不停的回调该方法)        @Override        public void onNewFrame() {            super.onNewFrame();            //获取当前视频的播放时间位置            int currentPosition = (int) vr_video.getCurrentPosition();            //设置seekBar的进度条            seek_bar.setProgress(currentPosition);            //显示播放的进度数字            tv_progress.setText("播放进度:" + String.format("%.2f", currentPosition / 1000.f));        }        //当视频播放结束后的回调        @Override        public void onCompletion() {            super.onCompletion();            //让视频回到0点            vr_video.seekTo(0);            //视频停止            vr_video.pauseVideo();            //让进度条也设置到0点            seek_bar.setProgress(0);            //播放完成后,重新设置标签,标签true代表着视频处于暂停的状态.            isPaused = false;        }        //设置一个视频播放状态的标签        private boolean isPaused = true;        //重写点击视图的方法,是视频被点击时,播放或者暂停        @Override        public void onClick() {            super.onClick();            //根据标签,判断当前视频的状态,做对应的逻辑处理            //false是不是代表视频正处于暂停状态,            if (isPaused) {                //视频暂停                vr_video.pauseVideo();            }            //true是不是代表视频正在播放的状态.            else {                //视频播放                vr_video.playVideo();            }            //对标签进行一次操作后,取反            isPaused = !isPaused;        }    }}
效果图

到这里VR小项目全面完工如有疑问欢迎留言!
VR小项目(一)
VR小项目(二)
VR小项目(三)


1 0
原创粉丝点击