【问题标题】:Get active page in ViewPager and update content在 ViewPager 中获取活动页面并更新内容
【发布时间】:2017-04-04 23:21:10
【问题描述】:

我按照下面的教程(向下滚动到“全屏图像幻灯片”部分)来实现全屏幻灯片,除了在幻灯片中不使用图像,我使用的是视频:

http://www.androidhive.info/2016/04/android-glide-image-library-building-image-gallery-app/

这是我对 DialogFragment 和 PagerAdapter 的实现:

public class SlideshowDialogFragment extends DialogFragment {

    private ArrayList<Video> videos;

    private ViewPager viewPager;

    private MyViewPagerAdapter myViewPagerAdapter;

    private int selectedPosition = 0;

    public static SlideshowDialogFragment newInstance() {
        SlideshowDialogFragment fragment = new SlideshowDialogFragment();

        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_slideshow, container, false);

        videos = (ArrayList<Video>) getArguments().getSerializable("videos");
        selectedPosition = getArguments().getInt("position");

        viewPager = (ViewPager) v.findViewById(R.id.viewPager);

        myViewPagerAdapter = new MyViewPagerAdapter();
        viewPager.setAdapter(myViewPagerAdapter);

        setCurrentItem(selectedPosition);

        return v;
    }

    private void setCurrentItem(int position) {
        viewPager.setCurrentItem(position, false);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    }

    public class MyViewPagerAdapter extends PagerAdapter {

        private LayoutInflater layoutInflater;

        public MyViewPagerAdapter() {

        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View view = layoutInflater.inflate(R.layout.video_layout, container, false);

            Video video = videos.get(position);

            TextureVideoView videoView = (TextureVideoView) view.findViewById(R.id.videoView);

            Uri videoUri = Uri.parse(video.getUrl());

            videoView.setVideoURI(videoUri);
            videoView.setMediaController(null);
            videoView.requestFocus();

            container.addView(view);

            return view;
        }

        @Override
        public int getCount() {
            return videos.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object obj) {
            return view == ((View) obj);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}

问题是,现在,视频一加载就会自动播放。而且,由于 ViewPager 加载了下一张和上一张幻灯片(我希望它这样做),幻灯片也会自动播放下一张和上一张视频(我希望它这样做)。

所以我的问题是,如何修改我的代码,使其仅在当前幻灯片处于活动状态时播放视频,然后在幻灯片变为非活动状态时暂停/停止视频?

仅供参考:开始和停止视频的方法是videoView.start()videoView.stop()

【问题讨论】:

    标签: android android-layout android-fragments android-viewpager


    【解决方案1】:

    您可以使用我的其他答案 here 中的相同方法。

    在 ViewPager 适配器中保留一组视频视图引用,以便您可以启动当前正在显示的视频,并暂停所有已实例化但当前未显示的视频视图。

    对适配器的更改:

    public class MyViewPagerAdapter extends PagerAdapter {
    
        private LayoutInflater layoutInflater;
    
        //Added:
        public TextureVideoView[] videoViews = new TextureVideoView[videos.size()];
    
        public MyViewPagerAdapter() {
    
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            View view = layoutInflater.inflate(R.layout.video_layout, container, false);
    
            Video video = videos.get(position);
    
            TextureVideoView videoView = (TextureVideoView) view.findViewById(R.id.videoView);
    
            Uri videoUri = Uri.parse(video.getUrl());
    
            videoView.setVideoURI(videoUri);
            videoView.setMediaController(null);
            videoView.requestFocus();
    
            container.addView(view);
    
            //Added:
            videoViews[position] = videoView;
    
            return view;
        }
    
        //.............
    }
    

    然后,在适配器之外,使用 ViewPager.OnPageChangeListener 启动当前视频,并暂停任一侧的视频:

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
    
      @Override
      public void onPageSelected(int position) {
    
        for (int i = 0; i < videos.size(); i++) {
          TextureVideoView videoView = myViewPagerAdapter.videoViews[i];
          if (videoView == null) continue;
          if (i == position) {
            videoView.start();
          } else {
            videoView.stop();
          }
        }
      }
    
      @Override
      public void onPageScrollStateChanged(int state) {  }
    });
    

    【讨论】:

    • 效果很好,谢谢!我应该注意任何性能问题吗?
    • 很高兴它有效!在性能方面应该很好。 onPageSelected 中的那个循环应该只需要开始当前视频,并停止两边的两个视频。唯一会出现问题的方法是,如果您有大量页面,并且还修改了屏幕外页面限制,使其大于 2。只要您保留默认的屏幕外页面限制,就可以了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2019-12-29
    相关资源
    最近更新 更多