新技术VR—应用案例项目分解

新技术VR—应用案例项目分解_第1张图片

首先搭建项目环境

  • 1.1.依赖 http库,gson库,RecyclerView+CardView库,design包,Glide库,butterknife库,Adapter-Helper库(BaseQuickAdapter)

  • 1.2.还需搭建vr开发环境.

    1.2.1.导入vr开发相关的库 common, commonwidget,通用。全景图片panowidget,全景视频videowidget
    1.2.2.配置应用获取最大内存,防止内存不足选成内存溢出

然后 搭建UI界面

  • 2.1.删除ActionBar只在主题风格下面进行NoActionBar配置即可

  • 2.2.布局指示器TabLayout 布局ViewPager

  • 2.3.查找出来进行初始化

  • 2.3.1.创建适配器给ViewPager

配置清单文件 AndroidManifest


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.vrproject97">
    
    <uses-permission android:name="android.permission.INTERNET" />
    
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:name=".VrApp"

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            intent-filter>
        activity>
        <activity android:name=".activity.VrImagePlayActivity" />
        <activity android:name=".activity.VrVideoDesActivity" />
        <activity android:name=".activity.VrVideoPlayActivity" />
    application>

manifest>

初始化联网配置—VrApp.java

public class VrApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate(); 
        //NoHttp初始化简单配置
        NoHttp.initialize(this);
    }
}

创建自定义控件——StateLayout

新技术VR—应用案例项目分解_第2张图片
展示联网的几种加载状态,所显示的默认图片

//步骤一 。完成构造函数
public class StateLayout extends FrameLayout {
    private View mLoading = null;
    private View mError = null;
    private View mEmpty = null;
    private View mNormal = null;

    public StateLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //步骤二 将布局打气进来并且作为一个元素添加当前的容器
        View view = View.inflate(context, R.layout.state_layout, null);
        mLoading = view.findViewById(R.id.loading);
        mError = view.findViewById(R.id.error);
        mEmpty = view.findViewById(R.id.nodata);
//      mNormal = view.findViewById(R.id.normal);
        this.addView(view);
    }

    public StateLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StateLayout(Context context) {
        this(context, null, 0);
    }

    //三。重置让所有的控件变成gone
    private void reset() {
        mLoading.setVisibility(View.GONE);
        mError.setVisibility(View.GONE);
        mEmpty.setVisibility(View.GONE);
        if (mNormal != null) {
            mNormal.setVisibility(View.GONE);
        }

    }

    //显示加载中
    public void showLoading() {
        reset();
        mLoading.setVisibility(View.VISIBLE);
    }

    //显示网络出错
    public void showError() {
        reset();
        mError.setVisibility(View.VISIBLE);
    }

    //显示空
    public void showEmpty() {
        reset();
        mEmpty.setVisibility(View.VISIBLE);
    }

    public void addNormalView(Object normalViewLayout) {
        if (normalViewLayout instanceof Integer) {
            mNormal = LayoutInflater.from(getContext()).inflate((Integer) normalViewLayout, this, false);
        } else {
            mNormal = (View) normalViewLayout;
        }
        this.addView(mNormal);//只有添加到当前布局的元素才可以显示
    }

    //显示正常
    public void showNormal() {
        reset();
        mNormal.setVisibility(View.VISIBLE);
    }

}

布局界面 state_layout.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ProgressBar
        android:id="@+id/loading"
        style="@android:style/Widget.ProgressBar.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone" />
    
    <TextView
        android:id="@+id/error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:drawablePadding="10dp"
        android:drawableTop="@drawable/ic_error_page"
        android:gravity="center_horizontal|bottom"
        android:text="加载失败,点击重试"
        android:visibility="gone" />
    
    <ImageView
        android:id="@+id/nodata"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_empty_page" />

    
    
        
        
        
        
        
        
        
FrameLayout>

工具类的使用

ApiUrls

地址工具类,方便以后更改地址

public class ApiUrls {
    public static final String HOST="http://192.168.191.1:8080";
    public static final String IMAGE_LIST=HOST+"/vr/imagelist";
    public static final String VIDEO_LIST=HOST+"/vr/videolist";
}

HttpUtils

封装联网工具

public class HttpUtils {
    private static RequestQueue queue;
    public static void get(String url, OnResponseListener callBack) {
        //创建请求xml/json
        StringRequest request = (StringRequest) NoHttp.createStringRequest(url, RequestMethod.GET);//1.连接地址 2.请求方法
        //设置缓存模式
        request.setCacheMode(CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE);
        if (queue == null) {
            queue = NoHttp.newRequestQueue();
        }
        // 1.提供多个空的方法 编写业务逻辑
        //2.每个方法都对应一个情况  成功 失败
        queue.add(0, request, callBack);//1.请求what 2.请求 3.回调对象:处理结果的对象。
    }
}

主页面代码

新技术VR—应用案例项目分解_第3张图片
界面布局 activity_main.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.itheima.vrproject97.activity.MainActivity">
    
    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/tabs">
    android.support.design.widget.TabLayout>
    
    <android.support.v4.view.ViewPager
        android:layout_marginTop="50dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/viewpager">
    android.support.v4.view.ViewPager>
FrameLayout>

MainActivity的代码

public class MainActivity extends AppCompatActivity {
    @InjectView(R.id.tabs)
    TabLayout tabs;
    @InjectView(R.id.viewpager)
    ViewPager viewpager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);

        MainFragmentAdapter adapter = new MainFragmentAdapter(getSupportFragmentManager());
        viewpager.setAdapter(adapter);
        //2.3.2设置tabLayout外观
        //字体
        tabs.setTabTextColors(Color.parseColor("#707070"),Color.parseColor("#FF9648"));
        //滑块颜色
        tabs.setSelectedTabIndicatorColor(Color.parseColor("#FF9648"));
        //滑块高度
        tabs.setSelectedTabIndicatorHeight(4);

        //2.3.3.把ViewPager设置给TabLayout
        tabs.setupWithViewPager(viewpager);
    }

    private class MainFragmentAdapter extends FragmentPagerAdapter {
        private String[] mTitles = new String[]{"全景图", "全景视频"};
        private Fragment[] mPages = new Fragment[]{new VrPanoFragment(), new VrVideoFragment()};

        public MainFragmentAdapter(FragmentManager fm) {
            super(fm);
        }

        //返回指示需要的标题
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles[position];
        }

        //返回页面内容
        @Override
        public Fragment getItem(int position) {
            return mPages[position];
        }

        //返回页面数量
        @Override
        public int getCount() {
            return mTitles.length;
        }
    }
}

全景图片的Fragment展示

新技术VR—应用案例项目分解_第4张图片

VrPanoFragment

public class VrPanoFragment extends BaseFragment {

}

抽取Fragment的基类 BaseFragment

BaseFragment

public class BaseFragment extends Fragment {

    private StateLayout stateLayout;
    protected RecyclerView recyclerView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //步骤一。创建页面基本组成
        //1.1.创建StateLayout实例
        stateLayout = new StateLayout(container.getContext());
        //1.2.创建列表RecyclerView
        recyclerView = new RecyclerView(container.getContext());
        //1.3.显示方式
        recyclerView.setLayoutManager(getLayout(container));
        stateLayout.addNormalView(recyclerView);
        //1.4.显示loading
        stateLayout.showLoading();
        //步骤二。获取服务端数据进行显示
        //2.1.阅读接口文档,测试接口正常 http://192.168.79.34:8080/vr/imagelist
        //2.2.发送请求(nohttp框架初始化)
        getPageData();
        return stateLayout;
    }

    public void getPageData() {
        //2.3.在Callback对应条件的空方法里编写业务逻辑
       final OnResponseListener callBack = new OnResponseListener() {
            @Override
            public void onStart(int what) {
                stateLayout.showLoading();
            }
            @Override
            public void onFinish(int what) {
                stateLayout.showNormal();
            }
            @Override
            public void onFailed(int what, Response response) {
                stateLayout.showError();
            }
            @Override
            public void onSucceed(int what, Response response) {
                //2.4.获取返回的json数据
                String json=response.get();
                //2.5.如果没问题再使用gsonFormat来解析
                Object data = processJson(json);
                //2.6展示数据
                showData(data);
            }
        };
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                HttpUtils.get(loadUrl(), callBack);
            }
        }, 1000);
    }

    @NonNull
    protected RecyclerView.LayoutManager getLayout(@Nullable ViewGroup container) {
        return new LinearLayoutManager(container.getContext());
    }
    @NonNull
    protected String loadUrl() {
        return ApiUrls.IMAGE_LIST;
    }

    protected Object processJson(String json) {
        return new Gson().fromJson(json,ImageData.class);
    }

    protected void showData(Object data) {
        ImageData imageData= (ImageData) data;
        System.out.println(data);
        //步骤三。展示解析成功的数据
        VrPanoAdaper adapter=new VrPanoAdaper(R.layout.item_image_card,imageData.list);
        recyclerView.setAdapter(adapter);
    }
}

ImageData 的bean类

public class ImageData {

    public List list;

    public static class ImageItem implements Serializable{
        /**
         * mp3 : http://media.qicdn.detu.com/@/13363707-8857-C248-3CE1-64F2F24291636/source/145049/o_1arbdk2apj37df16up16um196j7.mp3
         * title : 滕王阁
         * url : http://media.qicdn.detu.com/pano177051472357986990056825/thumb/500_500/panofile.jpg
         */
        public String mp3;
        public String title;
        public String url;
    }
}

界面布局 item_image_card.xml


<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="6dp"
    card:cardCornerRadius="6dp"
    card:cardElevation="10dp">
    
    
    
    <include layout="@layout/item_image" />

界面布局 item_image.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image"
        android:scaleType="centerCrop"
        android:layout_width="match_parent"
        android:layout_height="150dp" />
    <TextView
        android:layout_marginTop="6dp"
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="--"
        android:textColor="#000000"
        android:textSize="22sp" />
LinearLayout>

创建适配器 VrPanoAdaper
继承快速的适配器,在适配器中设置内容,设置点击事件

//3.1.创建适配器类
public class VrPanoAdaper extends BaseQuickAdapter<ImageData.ImageItem> {
    //3.2.指定布局给适配器
    public VrPanoAdaper(int layoutResId, List data) {
        super(layoutResId, data);
    }

    //3.3.赋值
    @Override
    protected void convert(BaseViewHolder helper, final ImageData.ImageItem item) {
        //3.3.1赋值
        helper.setText(R.id.text, item.title);
        //3.3.2.加载图片
        Glide.with(mContext).load(item.url).into((ImageView) helper.getView(R.id.image));
        helper.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(v.getContext(), VrImagePlayActivity.class);
                intent.putExtra("item",item);//要求javaBean实现序列化 implements Serializable
                v.getContext().startActivity(intent);//打开
            }
        });
    }
}

设置条目点击事件转到展示页面—VrImagePlayActivity

新技术VR—应用案例项目分解_第5张图片

public class VrImagePlayActivity extends AppCompatActivity {

    private VrPanoramaView vrPanoramaView;
    private ImageTask imageTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent=getIntent();
        ImageData.ImageItem item= (ImageData.ImageItem) intent.getSerializableExtra("item");
        //步骤一。搭建VR图片开发的环境
        //1.1.导入从github搜索下载的google vr sdk 里面的引用库 common,commonwidget,panowidget(全景图片控件库)
        //1.2.当前这三个库里面缺少序列相关的api,容易引用类找不到,未定义异常
        //1.3.依赖三个库
        //1.4.准备全景图片用来测试代码 放在assets目录下面,例assets/a.jpg
        //1.5.对当前应用进行内存设置,希望应用可使用最大内存 避免OOM  
        //步骤二。加载全景图片到内存中成为Bitmap(bitmap是图片在内存中的表示对象),展示在全景图片控件
        //2.1.布局全景图片控件
        //2.2.查找控件
        vrPanoramaView = new VrPanoramaView(this);
        setContentView(vrPanoramaView);
        //2.3.因为图片比较大,希望在异步线程里面加载,防止占用主线程
        imageTask = new ImageTask();
        imageTask.execute(item.url);
    }
    private class ImageTask extends AsyncTask<String,Void,Bitmap>
    {
        //2.4.读取资产目录下面的a.jpg图片
        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                //2.4.1.获取网络流
                URL url=new URL(params[0]);
                HttpURLConnection connection= (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(10000);
                InputStream inputStream =connection.getInputStream();
                //2.4.2.使用BitmapFactory可以将inputStream,file,byte[]-->Bitmap
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        //2.5.在主线程展示位图
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(bitmap!=null)
            {
                //加载bitmap到vr图片控件  参1.Bitmap
                VrPanoramaView.Options options=new VrPanoramaView.Options() ;
                //TYPE_STEREO_OVER_UNDER :立体图片:上半画面显示在左眼,下半画面显示在右眼
                //TYPE_MONO :普通图片
                options.inputType= VrPanoramaView.Options.TYPE_MONO;
               //3.1.监听加载过程
                VrPanoramaEventListener listener=new VrPanoramaEventListener(){
                    //3.1.1.加载bitmap异常
                    @Override
                    public void onLoadError(String errorMessage) {
                        super.onLoadError(errorMessage);
                        Toast.makeText(VrImagePlayActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
                    }
                    //3.1.2.加载bitmap成功
                    @Override
                    public void onLoadSuccess() {
                        super.onLoadSuccess();
                        Toast.makeText(VrImagePlayActivity.this, "进入VR图片显示...", Toast.LENGTH_SHORT).show();
                    }
                };
                vrPanoramaView.setEventListener(listener);
                vrPanoramaView.loadImageFromBitmap(bitmap,options);
            }
        }
    }
    //步骤三。处理全景控件展示细节
    //3.2.页面停到后台,暂停画面显示
    @Override
    protected void onPause() {
        super.onPause();
        if (vrPanoramaView != null) {
            vrPanoramaView.pauseRendering();
        }
    }
    //3.3.页面回到屏幕,再继续显示
    @Override
    protected void onResume() {
        super.onResume();
        if (vrPanoramaView != null) {
            vrPanoramaView.resumeRendering();
        }
        //3.5.按钮控制
        //3.5.1隐藏info按钮
        vrPanoramaView.setInfoButtonEnabled(false);
        //3.5.2隐藏全屏按钮
        vrPanoramaView.setFullscreenButtonEnabled(false);
        //3.5.3.展示全屏
        //FULLSCREEN_MONO 全屏模式
        //FULLSCREEN_STEREO CardBoard 纸盒
        vrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_MONO);
    }

    //3.4.页面关闭,销毁图片
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vrPanoramaView != null) {
            vrPanoramaView.shutdown();
        }
        if (imageTask != null && !imageTask.isCancelled()) {
            //防止页面退出AsyncTask引用的异常
            imageTask.cancel(true);
            imageTask = null;
        }
    }
}

到这,图片的fragment的页面就已经设置好了

全景视频页面

VrVideoFragment

新技术VR—应用案例项目分解_第6张图片

public class VrVideoFragment extends BaseFragment {
    //1.指定新的请求路径
    @Override
    protected String loadUrl() {
        return ApiUrls.VIDEO_LIST;
    }
    //2.重写排列方式
    @NonNull
    @Override
    protected RecyclerView.LayoutManager getLayout(@Nullable ViewGroup container) {
        GridLayoutManager gridLayoutManager = new GridLayoutManager(container.getContext(), 2);
        return gridLayoutManager;
    }
    //3.处理服务端返回数据
    @Override
    protected Object processJson(String json) {
        return new Gson().fromJson(json, VideoData.class);
    }
    //4.展示视频数据
    @Override
    protected void showData(Object data) {
        VideoData videoData = (VideoData) data;

        VrVideoAdapter vrVideoAdapter=new VrVideoAdapter(R.layout.item_video_card,videoData.content);
        recyclerView.setAdapter(vrVideoAdapter);
    }
}

VideoData 的bean类

public class VideoData {
 public String api;
    public int qtime;
    public int status;
    public String message;
    public String accessKey;
    public String voipId;
    public String voipPwd;
    public List content;
    public static class VideoItem  implements Serializable{
    public String vtype;
        public String id;
        public String key;
        public String play;
        public String title;
        public String text;
        public String img;
        public String url;
        public String isbn;
        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 double score0;
        public long date;
        public String _id;
        public String userId;
        public int cnt;
        public String type;
        public String videoChannelName;
        public String videoChannelId;
        public String textSimple;
        public String dateCnSimple;
        public List tags;
    }
}

item_video_card.xml


<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="6dp"
    card:cardCornerRadius="6dp"
    card:cardElevation="10dp">
    
    
    
    <include layout="@layout/item_video" />
android.support.v7.widget.CardView>

item_video.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/text"
        android:maxLines="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:text="--"
        android:textColor="#000000"
        android:textSize="16sp" />

    <RelativeLayout
        android:layout_marginTop="4dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="电影"
            android:maxLines="1"
            android:layout_centerVertical="true"
            android:textColor="#000000"
            android:textSize="16sp" />
        <TextView
            android:id="@+id/date"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_width="wrap_content"
            android:maxLines="1"
            android:layout_height="wrap_content"
            android:text="2017/10/1"
            android:textColor="#000000"
            android:textSize="16sp" />
    RelativeLayout>
LinearLayout>

VrVideoAdapter

//1.继承 BaseQuickAdapter指定类型
public class VrVideoAdapter extends BaseQuickAdapter<VideoData.VideoItem> {
    //2.设置布局与集合
    public VrVideoAdapter(int layoutResId, List data) {
        super(layoutResId, data);
    }

    //3.绑定数据
    @Override
    protected void convert(BaseViewHolder helper, final  VideoData.VideoItem item) {
       //3.1.绑定文字
        SimpleDateFormat formate=new SimpleDateFormat("yyyy/MM/dd");
        helper.setText(R.id.text,item.title)//
                .setText(R.id.type,item.type)//
                .setText(R.id.date,formate.format(new Date(item.date)));//
        //3.2.加载图片
        Glide.with(mContext).load(item.img).into((ImageView)helper.getView(R.id.image));
        //添加点击事件
        helper.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(v.getContext(),VrVideoDesActivity.class);
                intent.putExtra("item",item);
                v.getContext().startActivity(intent);
            }
        });

    }
}

转到视频详情页面—VrVideoDesActivity
新技术VR—应用案例项目分解_第7张图片

public class VrVideoDesActivity extends AppCompatActivity {
    @InjectView(R.id.title_text)
    TextView titleText;
    @InjectView(R.id.control_bar)
    LinearLayout controlBar;
    @InjectView(R.id.detail_img_view)
    ImageView detailImgView;
    @InjectView(R.id.video_type)
    TextView videoType;
    @InjectView(R.id.play_link)
    ImageButton playLink;
    @InjectView(R.id.detail_text)
    TextView detailText;
    @InjectView(R.id.video_detail)
    FrameLayout videoDetail;
    private VideoData.VideoItem item;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_detail);
        ButterKnife.inject(this);
        Intent intent = getIntent();
        final VideoData.VideoItem item =  (VideoData.VideoItem) intent.getSerializableExtra("item");
        System.out.println(item);
        //设置标题
        titleText.setText(item.title);
        //详情
        detailText.setText(item.textSimple);
        //图片
        Glide.with(this).load(item.img).into(detailImgView);
        playLink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(v.getContext(),VrVideoPlayActivity.class);
                intent.putExtra("play",item.play);
                v.getContext().startActivity(intent);
            }
        });

    }
}

activity_video_detail .xml


<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="#FFFFFF" >

    <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_margin="4dp"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="@color/gray_lighter"
                android:orientation="horizontal" >
                <ImageView
                    android:id="@+id/detail_img_view"
                    android:background="@color/black"
                    android:layout_width="match_parent"
                    android:scaleType="centerCrop"
                    android:clickable="true"
                    android:layout_height="200dp"
                    android:src="@mipmap/pictures_no"/>
                <TextView
                    android:id="@+id/video_type"
                    android:padding="8dp"
                    android:textStyle="bold"
                    android:background="@color/semitransparent_light"
                    android:text="视频"
                    android:textColor="#FFFFFF"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <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="#AEAEAE"
                android:textSize="16sp" />


        LinearLayout>
    ScrollView>

FrameLayout>

activity_vr_videoplay.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <com.google.vr.sdk.widgets.video.VrVideoView
        android:layout_width="match_parent"
        android:id="@+id/vr_video_view"
        android:layout_height="match_parent">
    com.google.vr.sdk.widgets.video.VrVideoView>
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <SeekBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/seekbar" />
        <TextView
            android:background="#AEAEAE"
            android:textColor="#FFFFFF"
            android:text="00/100s"
            android:layout_width="wrap_content"
            android:gravity="center"
            android:layout_height="wrap_content"
            android:id="@+id/time" />
    LinearLayout>
    <ProgressBar
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:id="@+id/loading"
        android:layout_height="wrap_content" />
RelativeLayout>

VrVideoPlayActivity
播放页面有加载页面和进度条

新技术VR—应用案例项目分解_第8张图片

新技术VR—应用案例项目分解_第9张图片

public class VrVideoPlayActivity extends AppCompatActivity {

    private VrVideoView vrVideoView;
    private VideoTask videoTask;
    private ProgressBar progressBar;
    private TextView timeView;
    private SeekBar seekBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vr_videoplay);
        //步骤一。搭建全景视频的开发环境
        //1.1.导入github搜索google vr sdk 的开发库 common,commonwidget,videowidget
        //1.2.依赖 当前三个库缺少的api
        //1.3.准备全景视频来测试程序 ,放到assets下面 例 assets/b.mp4
        //1.4. 设置应用的内存选项,在内存不足时可以使用最大内存. 
        //步骤二。在线程加载全景视频,显示在全景视频控件上
        //2.1.布局控件并查找
        vrVideoView = (VrVideoView) findViewById(R.id.vr_video_view);
        //2.2 创建子线程加载资源
        videoTask = new VideoTask();
        //2.3.传入文件名
        String play=getIntent().getStringExtra("play");
        videoTask.execute(play);

        seekBar = (SeekBar) findViewById(R.id.seekbar);
        timeView = (TextView) findViewById(R.id.time);
        progressBar = (ProgressBar) findViewById(R.id.loading);

        //步骤五。界面设置
        //5.1.设置隐藏info
        vrVideoView.setInfoButtonEnabled(false);
        //5.2.设置隐藏全屏
        vrVideoView.setFullscreenButtonEnabled(false);
        //5.3.显示全屏
        //FULLSCREEN_MONO全屏模式
        //FULLSCREEN_STEREO双眼模式
        vrVideoView.setDisplayMode(VrWidgetView.DisplayMode.EMBEDDED);

    }

    private class VideoTask extends AsyncTask {
        @Override
        protected Void doInBackground(String... params) {
            //2.4.从资产目录加载全景视频(类似ProgressBar因为这种控件可以自己处理线程)
            VrVideoView.Options options = new VrVideoView.Options();//设置参数
            //立体视频:上半画面显示在左眼,下半画面显示在右眼
            //普通视频:
            options.inputType = VrVideoView.Options.TYPE_MONO;
            //FORMAT_DEFAULT:资源 sd assets
            //FORMAT_HLS :流媒体  直播
            options.inputFormat = VrVideoView.Options.FORMAT_DEFAULT;
            //步骤四:监听加载过程 播放过程
            VrVideoEventListener listener = new VrVideoEventListener() {
                //4.1.加载成功 处理加载成的显示
                @Override
                public void onLoadSuccess() {
                    super.onLoadSuccess();
                    progressBar.setVisibility(View.GONE);
                }

                //4.2.加载失败
                @Override
                public void onLoadError(String errorMessage) {
                    super.onLoadError(errorMessage);
                    progressBar.setVisibility(View.GONE);
                    Toast.makeText(VrVideoPlayActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
                }

                //4.3.播放中 onNewFrame执行一次,代表视频播了一个画面
                @Override
                public void onNewFrame() {
                    super.onNewFrame();
                    //更新seekbar
                    seekBar.setMax((int) vrVideoView.getDuration());
                    seekBar.setProgress((int) vrVideoView.getCurrentPosition());
                    //更新时间 23.323232323
                    String curr = String.format("%.2f", vrVideoView.getCurrentPosition() / 1000f);
                    String total = String.format("%.2f", vrVideoView.getDuration() / 1000f);
                    timeView.setText(curr + "/" + total + "s");
                }
                //4.4.播放完成
                @Override
                public void onCompletion() {
                    super.onCompletion();
                    //设置播放位置
                    vrVideoView.seekTo(0);
                    //暂停播放
                    vrVideoView.pauseVideo();
                    isPasuse = true;
                    Toast.makeText(VrVideoPlayActivity.this, "播放完成,是否重播", Toast.LENGTH_SHORT).show();
                }

                private boolean isPasuse = false;

                //4.5.操作:点击继续播放
                @Override
                public void onClick() {
                    super.onClick();
                    if (isPasuse) {
                        vrVideoView.playVideo();
                        isPasuse = false;
                    } else {
                        vrVideoView.pauseVideo();
                        isPasuse = true;
                    }
                }
            };
            try {
                vrVideoView.setEventListener(listener);
                //加载网络视图 1.参数url 2.options
                vrVideoView.loadVideo(Uri.parse(params[0]),options);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    //步骤三。根据用户的操作来调整显示(性能优化,防止黑屏)
    //3.1.页面 退到后台  暂停显示
    @Override
    protected void onPause() {
        super.onPause();
        if (vrVideoView != null) {
            vrVideoView.pauseRendering();
        }
    }

    //3.2.页面 回到屏幕  打开显示
    @Override
    protected void onResume() {
        super.onResume();
        if (vrVideoView != null) {
            vrVideoView.resumeRendering();
        }
    }

    //3.3.页面  退出页面 销毁
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vrVideoView != null) {
            vrVideoView.shutdown();
        }
        if (videoTask != null && !videoTask.isCancelled()) {
            videoTask.cancel(true);
            videoTask = null;
        }
    }
}

你可能感兴趣的:(Android-开发技术)