如何在嵌套的ViewPager2内部使用VideoView实现视频播放?

问题描述

  • 我的意图是使用ViewPager2实现嵌套的ViewPager。每 横向滚动ViewPager的页面包含纵向滚动 ViewPager包含按类别列出的视频列表。视频 当页面对用户可见时自动播放,并在页面停止时自动播放 看不见的。
  • 我的解决方案:

CategoryPagerAdapter用于水平滚动ViewPager

public class CategoryPagerAdapter extends FragmentStateAdapter {

    List<Category> categories = new ArrayList<>();

    public CategoryPagerAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        Fragment fragment = new ListVideoFragment();
        Bundle args = new Bundle();
        // Send category id to ListVideoFragment
        // This fragment contains the vertical-scroll ViewPager
        args.putLong(ListVideopaperFragment.EXTRA_CATEGORY_ID,categories.get(position).getId());
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getItemCount() {
        return Math.max(categories.size(),0);
    }

    public void addCategories(List<Category> categories) {
        this.categories.addAll(categories);
        notifyDataSetChanged();
    }
   }

ListVideoPagerAdapter用于垂直滚动ViewPager

    public class ListVideoPagerAdapter extends FragmentStateAdapter {

    List<Video> videos = new ArrayList<>();

    public ListWallpaperPagerAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        Fragment fragment;         
        fragment = new VideoPreviewFragment();
        Bundle args = new Bundle();
        args.putString(EXTRA_VIDEO_URI,videos.get(position).getVideoPath());
        args.putLong(EXTRA_VIDEO_ID,videos.get(position).getId());
        fragment.setArguments(args);
        
        return fragment;
    }

    @Override
    public int getItemCount() {
        return Math.max(videos.size(),0);
    }

    public void addVideos(List<Video> videos) {
        this.videos.addAll(videos);
         notifyDataSetChanged();
    } 
   } 

这是片段VideoPreviewFragment,其中包含VideoView作为视频播放器,并且包含在垂直滚动ViewPager的每一页中。

 private static VideoPreviewFragment fragment = null;
    private VideoView videoView;
    private String videoURI;
    private long videoId;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            videoURI = args.getString(EXTRA_VIDEO_URI);
            videoId = args.getLong(EXTRA_VIDEO_ID);          
        }      
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.wallpaper_view,container,false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        videoView = requireActivity().findViewById(R.id.video_view);
        initializePlayer();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (videoView != null) {
            videoView.start();
            Log.d(TAG,"Playing video:" + videoURI);
        }
    }

    @Override
    public void onStop() {
        if (videoView != null && videoView.canPause()) {
            videoView.pause();
            Log.d(TAG,"Pause video: " + videoURI);
        }
        super.onStop();
    }

    @Override
    public void onDestroy() {
        videoView.stopPlayback();
        Log.d(TAG,"releasePlayer:" + videoURI); 
        super.onDestroy();
    }
 
    // When scrolling to another video,the current video will be not visible,stop playback
    @Override
    public void setMenuVisibility(boolean isVisible) {
        super.setMenuVisibility(isVisible);
        if (!isVisible) {
            videoView.stopPlayback();
            Log.d(TAG,"releasePlayer:" + videoURI);
        }
    }

    int currentPosition = 0;
    private void initializePlayer() {
        videoView.setVideoURI(getMedia(videoURI));
        videoView.seekTo(1);
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @SuppressLint("LongLogTag")
            @Override
            public void onPrepared(MediaPlayer mp) {
                Log.d(TAG,"onPrepared video: " + videoURI);
                mp.setLooping(true);
            }
        });
        
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @SuppressLint("LongLogTag")
            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.d(TAG,"onCompletion video: " + videoURI);
                videoView.seekTo(0);
            }
        });
     
        videoView.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("LongLogTag")
            @Override
            public void onClick(View v) {
                Log.d(TAG,"onClick VideoView");
                if (videoView.isPlaying()) {
                    if (videoView != null && videoView.canPause()) {
                        videoView.pause();
                        Log.d(TAG,"Pause video: " + videoURI);
                    }
                    assert videoView != null;
                    currentPosition = videoView.getCurrentPosition();
                } else {
                    if (currentPosition >= 0){
                        videoView.seekTo(currentPosition);
                        if (videoView != null) {
                            videoView.start();
                            Log.d(TAG,"Playing video:" + videoURI + " duration : " + videoView.getDuration());
                        }
                    }
                }
            }
        });

    }

    private Uri getMedia(String videoSource) {
        if (URLUtil.isValidUrl(videoSource)) {
            return Uri.parse(videoSource);
        }
        return Uri.parse(videoSource);
    }
  }
  • 我的问题是,当应用运行时,列表中的第一个视频可以播放 通常,但是当我向下滚动到下一个视频时,它无法播放 视频,只是一个黑屏,尽管我可以在调试日志中看到 “正在播放视频:...”。当它发生时,它执行奇怪的行为 上下滚动,可以播放一些时间的视频,大部分 时间不能。

我还没弄清楚什么,您有任何想法吗?还是可以给我解决这个问题的等效解决方案?
谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)