我想在viewpager中播放不同片段的视频。我为每个片段使用多个媒体播放器和表面视图。当我向左或向右滑动时,我想暂停并启动视频。滑动到下一个视频完全没有问题但是当我滑动到上一个视频(已经在播放)时,表面视图重叠。同时,我可以毫无问题地播放和暂停视频。
我尝试了几乎所有setZorderMedia和setZOrderonTop的组合但是我失败了。
简而言之,问题是在viewpager中表面视图重叠。以下是问题相关的代码,布局和问题的屏幕截图。
包含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
<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
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方法中与问题相关的部分)
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;
}
});
滑动到下一个视频没问题;
回到之前暂停的视频;
如果还有其他必要信息,请询问。
答案 0 :(得分:2)
我认为您的问题是您正在为视频使用SurfaceView。
请尝试使用TextureView。
来自文档:
与SurfaceView不同,TextureView不会创建单独的窗口,而是表现为常规视图。这个关键区别允许移动,转换,动画等纹理
修改的
我不知道为什么投反对票,SurfaceView
会创建一个新窗口来绘制其内容。
(这是活动窗口的独立窗口,请参阅here)。
另请注意,在将表面视图的包含窗口附加到窗口管理器之前,需要调用zOrder调用,因此在创建和附加SurfaceViews
后,您无法重新排列SurfaceViews
的zOrder。
如果您确实想同时使用多个setVisibility (int visibility)
,则可以在切换页面时尝试在SurfaceView
上致电videoSurface
。
公开您的current.setVisibility(View.GONE)
变量,并在current.pause()
后current.setVisibility(View.VISIBLE)
和current.start()
之后SurfaceViews
致电{1}}。
我不确定这是否会奏效..
您最好的选择是每次更改页面时创建/销毁TextureView
,或者尝试使用我之前提到的{{1}}。