我有一个视频网址,我可以使用任何播放器或VideoView
播放。但这就是我想要做的事情。
RecyclerView
其中每个元素都包含视频的标题和缩略图。当用户点击视频时,会出现一个弹出窗口。此弹出窗口包含VideoView
(或任何可以播放来自网址的视频)并播放视频。用户可以拖动此窗口。诀窍是这样做,如果用户按下后退按钮,当前活动关闭,窗口应保持并继续播放视频。在播放视频时,用户可以在其他应用程序中执行任何操作,而带有视频的窗口仍然位于顶部并继续播放视频。用户可以随时按下窗口(或其中的按钮),视频将变为全屏。当用户决定全屏播放时,应用活动可能不在那里。
上面描述的内容已在此应用中实现
https://play.google.com/store/apps/details?id=com.djit.apps.stream&hl=en
我可以创建一个视图窗口,当用户关闭应用程序活动时,该窗口将保留在那里。为此我使用这个库
https://github.com/pingpongboss/StandOut
如果你检查了lib的源代码,你会看到StandOutWindow
是Service
,它会创建一个弹出窗口。
我实际上可以在这个窗口中播放视频。这是我的窗口类
public class FloatingWindow extends StandOutWindow {
private static final int WIDTH = 400;
private static final int HEIGHT = 361;
/*
I didn't think of a better way to set video url
therefore I made it static and set it with a static method
I know it is bad, but it works.
I will do it another way later
Now I have other issues
*/
private static String videoUrl = null;
public static void setVideoUrl(String videoUrl) {
FloatingWindow.videoUrl = videoUrl;
}
@Override
public String getAppName() {
return getApplicationContext().getResources().getString(R.string.app_name);
}
@Override
public int getAppIcon() {
return android.R.drawable.ic_menu_close_clear_cancel;
}
@Override
public void createAndAttachView(int id, FrameLayout frame) {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.floating_window, frame, true);
/*
As you can see I didn't use MediaController for this videoView
VideoView works with it, except for device
On this one device MediaController crashed the app with BadTokenException: token null is not valid, is your activity running
*/
final VideoView videoView = (VideoView) view.findViewById(R.id.textureVideoView);
final ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.videoProgressBar);
final ScrollView description = (ScrollView) view.findViewById(R.id.videoDescription);
videoView.setVideoURI(Uri.parse(videoUrl));
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
/*
I don't want my video view to be visible until it is ready
Because while it is preparing it gets transparent
But I want a progress bar instead
Therefore initially set its dimensions to 1x1 and change the size when it's ready
*/
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.CENTER;
videoView.setLayoutParams(params);
progressBar.setVisibility(View.GONE);
}
});
/*
When the activity is not present VideoView crashes when clicked
To avoid crash I overrided setOnTouchListener method and return true from it
*/
videoView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
if (videoView.isPlaying()) {
videoView.pause();
} else {
videoView.start();
}
}
return true;
}
});
}
@Override
public StandOutLayoutParams getParams(int id, Window window) {
return new StandOutLayoutParams(id, WIDTH, HEIGHT,
StandOutLayoutParams.CENTER, StandOutLayoutParams.CENTER);
}
@Override
public int getFlags(int id) {
return super.getFlags(id)
| StandOutFlags.FLAG_BODY_MOVE_ENABLE
| StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE
| StandOutFlags.FLAG_DECORATION_SYSTEM
| StandOutFlags.FLAG_ADD_FUNCTIONALITY_DROP_DOWN_DISABLE
| StandOutFlags.FLAG_DECORATION_CLOSE_DISABLE;
}
@Override
public String getPersistentNotificationMessage(int id) {
return "Click here to close floating window";
}
@Override
public Intent getPersistentNotificationIntent(int id) {
return StandOutWindow.getCloseIntent(this, FloatingWindow.class, id);
}
}
上面的代码有效,但有几个问题。
我在三台设备和模拟器上测试了它并且它工作正常。但是有一个设备首先崩溃了。我删除了MediaController
,现在几乎可以了。当用户更改窗口大小时,VideoView
大小会变得奇怪。也许我应该测试设备,代码不适用于Android兼容性。但是,无论如何也许我如何做窗口播放器是错误的,你知道更好的方法。
我必须将VideoView
的大小设置为1x1然后更改它,我不能立即使其正常大小,因为如果我这样做,{{1}窗口中的区域在视频加载之前,应该变得透明。此外,我无法单击VideoView
并让系统处理click事件。如果我这样做,我会得到VideoView
。活动未运行,因此我必须自己处理click事件以防止崩溃。这些黑客让我觉得我做错了。
我想不出一种让视频全屏的方法。我唯一想到的是启动全屏活动并将网址和视频位置传递给它。也许这是要走的路。在这种情况下,当用户点击全屏按钮时,用户将不得不等待视频再次加载。另外,我不知道在启动全屏活动时窗口的行为方式。
感觉视频不是在没有活动的情况下播放的。也许有办法让这个窗口播放器的方式总是存在一个不可见的活动,它会错过所有的触摸事件并将它们传递给活动堆栈。这样的活动可以用于视频播放。
答案 0 :(得分:0)
您可以通过使用以下尺寸对布局进行充气来使其全屏显示:
LayoutParams.y = getApplicationContext().getResources().getDisplayMetrics().heightPixels
LayoutParams.x = getApplicationContext().getResources().getDisplayMetrics().widthPixels