<ImageView
android:id=“@+id/play”
android:layout_width=“@dimen/x90”
android:layout_height=“@dimen/y90”
android:layout_gravity=“center_vertical”
android:src=“@mipmap/stop”/>
<SeekBar
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”/>
<TextView
android:id=“@+id/video_duration”
android:layout_width=“@dimen/x240”
android:layout_height=“wrap_content”
android:layout_gravity=“center_vertical”
android:textColor=“@color/colorFFFFFF”/>
<ImageView
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
<?xml version="1.0" encoding="utf-8"?>自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
感觉现在好多人都在说什么安卓快凉了,工作越来越难找了。又是说什么程序员中年危机啥的,为啥我这年近30的老农根本没有这种感觉,反倒觉得那些贩卖焦虑的都是瞎j8扯谈。当然,职业危机意识确实是要有的,但根本没到那种草木皆兵的地步好吗?
Android凉了都是弱者的借口和说辞。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
所以,最后这里放上我耗时两个月,将自己8年Android开发的知识笔记整理成的Android开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
d 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
所以,最后这里放上我耗时两个月,将自己8年Android开发的知识笔记整理成的Android开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
[外链图片转存中…(img-3B9U4Mca-1712766545147)]
以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!