android viewpager中的多个视频播放器 [英] Multiple video players in viewpager in android
问题描述
我想在viewpager中播放不同片段上的视频.我为每个片段使用了多个媒体播放器和Surfaceview.当我向左或向右滑动时,我也想暂停并开始播放视频.滑动到下一个视频根本没有问题,但是当我滑动到上一个视频(已经在播放)时,曲面视图会重叠.同时,我可以毫无问题地播放和暂停视频.
I want to play videos on different fragments in viewpager. I use multiple mediaplayers and surfaceviews for each fragment. When I swipe left or right, I want to pause and start videos as well. Swipe to next video has no problem at all but when i swipe to previous video(that is already playing) surfaceviews overlap. Meanwhile, I can play and pause videos without problem.
我尝试了setZorderMedia和setZOrderonTop的几乎所有可能组合,但是失败了.
I tried almost all possible combinations of setZorderMedia and setZOrderonTop but I failed.
简而言之,问题在于曲面视图在viewpager中重叠.这是与问题相关的代码,布局和问题的屏幕截图.
In short, the problem is that surfaceviews overlap in viewpager. Here are the problem related codes, layouts and a screenshot of the problem.
包含viewpager的活动的布局
Layout of the activity that contains viewpager
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_tweet_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".TweetActivity" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager_tweet"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
fragment layout.xml
Fragment layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/image_avatar"
android:layout_width="80dip"
android:layout_height="80dip" />
<TextView
android:id="@+id/text_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/image_avatar"
android:layout_marginLeft="18dp"
android:layout_toRightOf="@+id/image_avatar"
android:text="TextView"
android:textSize="7pt" />
<TextView
android:id="@+id/text_tweet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/image_avatar"
android:layout_below="@+id/image_avatar"
android:text="TextView"
android:textSize="7pt" />
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/video_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical"
android:layout_below="@+id/text_tweet" >
<FrameLayout
android:id="@+id/videoSurfaceContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<SurfaceView
android:id="@+id/videoSurface"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
</RelativeLayout>
</RelativeLayout>
Fragment.class
Fragment.class
private Context context=getActivity();
private View rootView;
private Typeface type;
private SurfaceView videoSurface;
private MediaPlayer player;
private VideoControllerView controller;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_tweet, container, false);
context=getActivity();
videoSurface = (SurfaceView) rootView.findViewById(R.id.videoSurface);
//videoSurface.setZOrderMediaOverlay(false);
//videoSurface.setZOrderOnTop(true);
SurfaceHolder videoHolder = videoSurface.getHolder();
videoHolder.addCallback(this);
player = new MediaPlayer();
controller = new VideoControllerView(context);
RelativeLayout videoView=(RelativeLayout) rootView.findViewById(R.id.video_container);
videoView.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
controller.show();
return false;
}
});
try {
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(context, Uri.parse("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"));
player.setOnPreparedListener(this);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return rootView;
}
// Implement SurfaceHolder.Callback
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
player.prepareAsync();
isSurfaceCreated=true;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
player.release();
}
// End SurfaceHolder.Callback
// Implement MediaPlayer.OnPreparedListener
@Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(this);
controller.setAnchorView((FrameLayout) rootView.findViewById(R.id.videoSurfaceContainer));
//player.start();
}
// End MediaPlayer.OnPreparedListener
// Implement VideoMediaController.MediaPlayerControl
@Override
public boolean canPause() {
return true;
}
@Override
public boolean canSeekBackward() {
return true;
}
@Override
public boolean canSeekForward() {
return true;
}
@Override
public int getBufferPercentage() {
return 0;
}
@Override
public int getCurrentPosition() {
return player.getCurrentPosition();
}
@Override
public int getDuration() {
return player.getDuration();
}
@Override
public boolean isPlaying() {
return player.isPlaying();
}
@Override
public void pause() {
player.pause();
}
@Override
public void seekTo(int i) {
player.seekTo(i);
}
@Override
public void start() {
player.start();
}
@Override
public boolean isFullScreen() {
return false;
}
@Override
public void toggleFullScreen() {
}
// End VideoMediaController.MediaPlayerControl
我的包含viewpager的活动(同样,该活动的onCreate方法中与问题相关的部分)
My activity that contains viewpager (again the problem related part in onCreate method of the activity)
currentFragment=pager.getCurrentItem();
pager.setOnPageChangeListener(new OnPageChangeListener(){
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int index) {
TweetFragment current=pagerAdapter.getItem(currentFragment);
current.pause();
TweetFragment selected=pagerAdapter.getItem(index);
selected.start();
currentFragment=index;
}
});
滑动到下一个视频没有问题;
Swipe to next video has no problem;
滑回之前已暂停的视频;
Swipe back to a video that is paused before;
如果还有其他必要的信息,请询问.
If there is anymore necessary information, please ask.
推荐答案
我认为您的问题是您正在为视频使用SurfaceView.
I think your problem is that you are using a SurfaceView for your video.
尝试使用 TextureView .
摘自文档:
与SurfaceView不同,TextureView不会创建单独的窗口,而是表现为常规的View.这种关键的区别允许对TextureView进行移动,转换,设置动画等.
Unlike SurfaceView, TextureView does not create a separate window but behaves as a regular View. This key difference allows a TextureView to be moved, transformed, animated, etc.
编辑
我不知道为什么投反对票的SurfaceView
会创建一个新窗口来绘制其内容.
(这是来自活动窗口的独立窗口,请参见此处 ).
I don't know why the negative vote, a SurfaceView
will create a new window to draw its content.
(This is an independent window from the window of the activity, see here ).
还请注意,在将表面视图的包含窗口附加到窗口管理器之前,需要先调用zOrder调用,以便您在创建并附加SurfaceViews
的zOrder后不能重新排列它们.
Also note that the zOrder calls need to be called before the surface view's containing window is attached to the window manager so you cant rearrange the zOrder of your SurfaceViews
after they are created and attached.
如果您确实想同时使用多个SurfaceViews
,则可以在切换页面时尝试在SurfaceView
上调用setVisibility (int visibility)
.
If you really want to use multiple SurfaceViews
at the same time you could try calling setVisibility (int visibility)
on your SurfaceView
when you switch pages.
公开您的videoSurface
变量,并在current.pause()
之后调用current.setVisibility(View.GONE)
,在current.start()
之后调用current.setVisibility(View.VISIBLE)
.
Make your videoSurface
variable public and call current.setVisibility(View.GONE)
after current.pause()
and current.setVisibility(View.VISIBLE)
after current.start()
.
我不确定那是否可以..
I'm not sure if that will work though..
您最好的选择是在每次更改页面时创建/销毁SurfaceViews
,或者尝试使用我之前提到的TextureView
.
Your best bet would be to either create/destroy the SurfaceViews
each time you change a page, or try using a TextureView
as I mentioned before.
这篇关于android viewpager中的多个视频播放器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!