#android #android-layout #android-viewpager #android-videoview #android-viewpager2
#Android #android-макет #android-viewpager #android-videoview #android-viewpager2
Вопрос:
- Я намерен реализовать вложенный ViewPager с использованием ViewPager2. Каждая страница 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
который содержит a 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 amp;amp; 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 amp;amp; 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);
}
}
- Моя проблема в том, что при запуске приложения может воспроизводиться первое видео в списке
обычно, но когда я прокручиваю вниз до следующего видео, оно не может воспроизводиться
видео, просто черный экран, хотя я могу видеть в журнале отладки
«Воспроизведение видео: …..». И он выполняет странное поведение, когда
прокручивая вверх и вниз, некоторое время можно воспроизводить видео, большая часть
время не может.
Я еще ничего не понял, у вас есть какие-нибудь идеи? Или вы можете дать мне эквивалентное решение для этого amtter?
Спасибо!
Комментарии:
1. Я обнаружил это из журнала отладки при прокрутке до следующего видео, оба
VideoView
из двухVideoPreviewFragment
, которые содержат проигрыватель, отсоединены от окна, поэтому видео 2nd не может воспроизводиться и отображается только черный экран. Я проверяю это, добавляяvideoView.addOnAttachStateChangeListener
. Но я не понимаю, почему это так. Это должно быть 1-еVideoView
отсоединенное и 2-еVideoView
прикрепленное к окну. Можете ли вы просветить меня по этому поводу.2. И при прокрутке назад к 1-му видео оба
VideoView
из двух проигрывателей подключены к окну. Итак, если я перейду к 3-му видео, а затем вернусь к 2-му видео, его можно воспроизвести. Какой странный