在android中的viewpager中的多个视频播放器

时间:2014-02-12 12:59:44

标签: android android-viewpager android-mediaplayer

我想在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

My VideoControllerView

我的活动包含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;
        }
    });

滑动到下一个视频没问题; Image 1

回到之前暂停的视频; Image 2

如果还有其他必要信息,请询问。

1 个答案:

答案 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}}。