视频在Fragment ViewPager中无法暂停

9
我正在使用带有碎片的 View Pager 来显示图片和视频,我能够正常显示图片和视频,但是我有一个问题,当我滑动到视频时,视频可以播放,但是当我向前或向后滑动时,视频仍然在下一个或上一个屏幕上播放,但是当我移动两个幻灯片时,视频会停止播放,但为什么不在下一个或上一个幻灯片上呢。
我进行了更多搜索,但没有找到任何解决方案,如果有任何帮助将不胜感激。 提前致谢。
这是我的代码:
这是 Fragment 类。
public class ContentFragment extends Fragment {
    private final String imageResourceId;
    private String type;


    public ContentFragment(String imageResourceId,String type) {
        System.out.println("Path In cons="+imageResourceId+"and type is="+type);
        this.imageResourceId = imageResourceId;
        this.type= type;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e("Test", "hello");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.content_layout, container, false);

        TouchImageView imageView = (TouchImageView) view.findViewById(R.id.touchImage);
        imageView.setImageResource(R.id.touchImage);
        imageView.setMaxZoom(10f);
        VideoView videoView =(VideoView) view.findViewById(R.id.videoView1);

        if(type.equals("image")) {
            imageView.invalidate();

            imageView.setVisibility(View.VISIBLE);
            videoView.setVisibility(View.GONE);

            try {
                System.out.println("IN Content Fragment"+imageResourceId.toString());

                Bitmap bmp = BitmapFactory.decodeFile(imageResourceId.toString());
                imageView.setImageBitmap(bmp);

            } catch(Exception e) {
                System.out.println("Error Of image File"+e);
            }


        } else  
        try {
        if(type.equals("video")){
            videoView.invalidate();
            videoView.setVisibility(View.VISIBLE);
            imageView.setVisibility(View.GONE);

            String path = imageResourceId.toString();
            videoView.setVideoURI(Uri.parse(path));
                videoView.setMediaController(new MediaController(getActivity()));
                videoView.setFocusable(true);
                videoView.start();
            }
        } catch(Exception e) {
        e.printStackTrace();
        }

        return view;
    }
}

这是分页适配器活动。
public class MediaActivity extends FragmentActivity {

     private MyAdapter mAdapter;
        private ViewPager mPager;


       public ArrayList<Content> contentList;
     Context context;
        LinearLayout numberOfPageLayout;
     SharedPreferences sharedPreferences;
     Handler progressHandler;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_media);
            context=(Context) getApplicationContext();                           
                    mPager = (ViewPager) findViewById(R.id.pager);
            progressHandler = new Handler();
            contentList=new ArrayList<Content>();
                new AsyncTask<Void, Void, Void>() {

                    @Override
                    protected Void doInBackground(Void... params) {
                        // TODO Auto-generated method stub
                        contentList=new ContentDBAdapter(context).getAllContent();

                        }           
                        return null;
                    }
                    @Override
                    protected void onPostExecute(Void result) {
                        // TODO Auto-generated method stub
                        super.onPostExecute(result);
                        mAdapter = new MyAdapter(getSupportFragmentManager(),contentList);
                        mPager.setAdapter(mAdapter);
                    }
                }.execute();




            mPager.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    // TODO Auto-generated method stub


                }

                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub

                }
            });
        }


        public static class MyAdapter extends FragmentPagerAdapter {
            ArrayList <Content>contList=new ArrayList<Content>();
            public MyAdapter(FragmentManager fm,ArrayList<Content> cont) {
                super(fm);
                this.contList=cont;
            }

            @Override
            public int getCount() {
                totalPage=contList.size();
                return contList.size();
            }

            @Override
            public Fragment getItem(int position) {

                Content con=contList.get(position);

                return new ContentFragment(con.getPath(),con.getType());

            }
        }

}

有人能告诉我它的解决方案吗? - Ankit
3个回答

14
这是因为ViewPager会保持离屏片段启动。例如,您有一个对用户可见的片段。 ViewPager将尝试保持前一个片段(在左侧)和下一个片段(在右侧)启动。这允许ViewPager在用户决定更改页面时执行平滑的滑动,因为下一页和上一页已经准备好了。
在您的情况下,视频播放器不可见(屏幕外),但由于上述行为,ViewPager仍在运行。您可以使用setOffscreenPageLimit()方法更改此行为。如果将页面限制设置为0,则屏幕外片段将立即暂停。不幸的是,它们不仅会被暂停,而且还会停止并与活动分离。这意味着当您返回到片段时,它将重新创建整个布局。这就是为什么您可以尝试覆盖Fragment.setUserVisibleHint()Fragment.onHiddenChanged()并在那里执行暂停/播放逻辑。 ViewPager将根据片段实际对用户是否可见来更新其隐藏状态。
希望这有所帮助。

感谢beworker的回答,但我用了另一种方法解决了这个问题,就像Android中的画廊应用程序一样,我没有直接使用视频视图,而是在图像视图中获取它的缩略图,然后在单击该缩略图后播放视频。但我会尝试你的解决方案。 - Ankit

9

在播放视频的片段中,您必须重写setUserVisibleHint方法。

public void setUserVisibleHint(boolean isVisibleToUser) {       
    super.setUserVisibleHint(isVisibleToUser);                         
     if (this.isVisible())
     {               
        if (!isVisibleToUser)   // If we are becoming invisible, then...
        {  
          //pause or stop video
        }

        if (isVisibleToUser) 
        {                               
            //play your video               
        }

    }

  }

当我停止/暂停播放器时,会出现非法异常,并且当我使用player.release()时,它会停止播放器,但无法播放下一个视频或当我返回时。 - Amal Kronz
我会将我的问题作为新问题添加,您可以看一下它: https://stackoverflow.com/questions/45052603/video-image-viewpager - Amal Kronz

0
我是这样处理问题的:
boolean isVisible = false;
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {

    isVisible = isVisibleToUser;
        if(player!=null)
            player.pause();       
    super.setUserVisibleHint(isVisibleToUser);
}

然后在onCreateView方法中:

SimpleExoPlayer player;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_screen_slide_page, container, false);
    PlayerView playerView = v.findViewById(R.id.playerView);
    playerView.getLayoutParams().width = ListPager.widthPixels;
    playerView.getLayoutParams().height = ListPager.widthPixels;
    if(player!=null)
         player.release();
    player = new SimpleExoPlayer.Builder(App.applicationContext).build();               
    playerView.setPlayer(player);
    MediaItem mediaItem = MediaItem.fromUri(url);
    player.setMediaItem(mediaItem);
    player.prepare();

    //---------The following code is important because if you remove the following if
    // then if the next page is displaying, android will automatically initiate the
    // previous and the next page, and the player will start playing :| 

    if(isVisible)
      player.play();
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接