android viewpager中的多个视频播放器 [英] Multiple video players in viewpager in android

查看:343
本文介绍了android viewpager中的多个视频播放器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我的VideoControllerView

我的包含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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆