android:id=“@+id/play” android:layout_width=“@dimen/x90” android:layout_height=“@dimen/y90” android:layout_gravity=“center_vertical” android:src=“@mipmap/stop”/> android:id=“@+id/video_progress” style=“@style/Widget.AppCompat.ProgressBar.Horizontal” android:layout_width=“@dimen/x600” android:layout_height=“@dimen/y100” android:layout_marginLeft=“@dimen/x_20”/> android:id=“@+id/video_duration” android:layout_width=“@dimen/x240” android:layout_height=“wrap_content” android:layout_gravity=“center_vertical” android:textColor=“@color/colorFFFFFF”/> android:id=“@+id/video_vr” android:layout_width=“@dimen/x90” android:layout_height=“@dimen/x90” android:layout_gravity=“center_vertical” android:src=“@mipmap/icon_vr”/> PlayerActivity public class PlayerActivity extends Activity implements View.OnClickListener { private VrVideoView mVideoView; private String mUrl; private TextView mVideoDuration; private SeekBar mSeekBar; private View mVideoPorgressContainer; private String mTotalDuration;//视频总时长, 00:08格式 private ImageView mPlayView; private boolean isPlaying; private View mVideoVr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_player); Intent intent = getIntent(); mUrl = intent.getStringExtra(“url”);//上一个Activity传递过来的url播放地址 initView(); initData(); initListener(); } @Override protected void onNewIntent(Intent intent) { setIntent(intent); //TODO handleIntent } private void initView() { mVideoView = (VrVideoView) findViewById(R.id.video_view); mPlayView = (ImageView) findViewById(R.id.play); mVideoDuration = (TextView) findViewById(R.id.video_duration); mSeekBar = (SeekBar) findViewById(R.id.video_progress); mVideoPorgressContainer = findViewById(R.id.video_progress_container); mVideoVr = findViewById(R.id.video_vr); mVideoView.setInfoButtonEnabled(false);//设置左侧信息原圈不可见 mVideoView.setFullscreenButtonEnabled(false);//设置全屏按钮不可见 mVideoView.setStereoModeButtonEnabled(false);//设置立体眼镜模式按钮不可见 } private void initData() { Uri uri; if (“”.equals(mUrl)) { uri = Uri.parse(“http://resource.vr-store.cn/appfile/6cc160ba38394af0a251d4275ea66c29.mp4”);//坝上的云 } else { uri = Uri.parse(mUrl); } VrVideoView.Options option = new VrVideoView.Options(); try { mVideoView.loadVideo(uri, option); } catch (IOException e) { e.printStackTrace(); } } private void initListener() { mPlayView.setOnClickListener(this); mVideoVr.setOnClickListener(this); mSeekBar.setOnSeekBarChangeListener(new SeekBarListener()); mVideoView.setEventListener(new VrVideoEventListener() { @Override public void onClick() { //处理控制面板的显示和隐藏 int visibility = mVideoPorgressContainer.getVisibility(); mVideoPorgressContainer.setVisibility(visibility == View.VISIBLE ? View.GONE : View.VISIBLE); } /** Make the video mPlayView in a loop. This method could also be used to move to the next video in a playlist. */ @Override public void onCompletion() { //播放完成后的操作 //mVideoView.seekTo(0);//循环播放效果 } @Override public void onNewFrame() { updateVideoProgress(); } @Override public void onLoadSuccess() { long duration = mVideoView.getDuration();//视频总时长,毫秒 mTotalDuration = RegularExpress.parseDuration(duration); mSeekBar.setMax((int) duration); } @Override public void onLoadError(String errorMessage) { super.onLoadError(errorMessage); Toast.makeText(PlayerActivity.this, “加载视频失败”, Toast.LENGTH_SHORT).show(); } @Override public void onDisplayModeChanged(int newDisplayMode) { super.onDisplayModeChanged(newDisplayMode); } }); } /** 更新播放进度 */ private void updateVideoProgress() { long currentPosition = mVideoView.getCurrentPosition(); String currentPos = RegularExpress.parseDuration(currentPosition); mSeekBar.setProgress((int) (currentPosition));//更新播放进度 StringBuilder sb = new StringBuilder(); sb.append(currentPos); sb.append(" / "); sb.append(mTotalDuration); mVideoDuration.setText(sb); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.play: performClickPlay(); break; case R.id.video_vr: performClickVideoVr(); break; default: break; } } private void performClickVideoVr() { mVideoView.setDisplayMode(3);//enterStereoMode,眼镜模式 } /** 播放暂停切换 */ private void performClickPlay() { if (isPlaying) { mVideoView.pauseVideo(); mPlayView.setImageResource(R.mipmap.play); isPlaying = false; } else { mVideoView.playVideo(); mPlayView.setImageResource(R.mipmap.stop); isPlaying = true; } } @Override protected void onPause() { super.onPause(); // Prevent the view from rendering continuously when in the background. mVideoView.pauseRendering(); // If the video is playing when onPause() is called, the default behavior will be to pause // the video and keep it paused when onResume() is called. isPlaying = false; } @Override protected void onResume() { super.onResume(); // Resume the 3D rendering. mVideoView.resumeRendering(); } @Override protected void onDestroy() { //https://developers.google.com/vr/android/reference/com/google/vr/sdk/widgets/common/VrWidgetView#shutdown() mVideoView.shutdown(); super.onDestroy(); } /** 播放器进度条监听 */ private class SeekBarListener implements SeekBar.OnSeekBarChangeListener { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { mVideoView.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { //手指离开进度条,三秒钟后隐藏控制面板 } } } 由于代码逻辑都比较简单,也都有注释,这里不再做过多的阐述。 下面介绍一下如何去除VR模式下界面上google自带的退出按钮和设置按钮。 集成过google vr或者玩过google vr sdk中提供的sample工程的童鞋都见过下面的两个按钮,在VR模式下,这两个按钮分别在页面的左上角和右上角。 去除方式多种多样,这里介绍比较简单实用的一种 在自己项目res/values/style.xml文件中添加如下样式: 那么中间的竖线如何去掉呢? 在自己项目的res/values/values.xml文件中添加如下代码: 0mm 0dip 112dip 效果如下: 为什么我们写一个style属性就能去掉返回和设置按钮呢? 查找源码发现com.google.vr:sdk-base1.10.0中layout文件夹下面有几个布局文件 back_button.xml 自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。 深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。 既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化! 由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新! 如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android) 最后 今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。 最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。 还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。 【Android核心高级技术PDF文档,BAT大厂面试真题解析】 【算法合集】 【延伸Android必备知识点】 《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取! ler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。 最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。 还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。 【Android核心高级技术PDF文档,BAT大厂面试真题解析】 [外链图片转存中…(img-LGqSLbcI-1712275563539)] 【算法合集】 [外链图片转存中…(img-KIeIZS9P-1712275563539)] 【延伸Android必备知识点】 [外链图片转存中…(img-ouwJ16ZJ-1712275563539)] 《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取! 好文推荐
上一篇
发表评论