PagerAdapter 总是在 ViewPager 中被调用两次

Posted

技术标签:

【中文标题】PagerAdapter 总是在 ViewPager 中被调用两次【英文标题】:PagerAdapter always getting called two times in ViewPager 【发布时间】:2021-12-27 13:42:46 【问题描述】:

我正在尝试在 TouchImageViewPlayerView (Exoplayer) 之间制作一个滑块,但即使经过多次更改,我也无法解决某些问题。欢迎所有的建议和答案。请原谅我的提问技巧,如果您的分析需要更多输入,请告诉我。如果有任何其他替代方案可以成功满足我对在ViewPager 中顺利实施视图的期望,还请告诉我。

问题描述:-

与点击视图相关的问题:-

    点击图片后,下一个视频(如果有)的音频开始在后台播放。 PlayerView 也有同样的问题。当点击视频缩略图时,点击的视频和下一个视频的音频一起播放。

与滑块相关的问题:-

    当我们滑动并到达视频之前的图像时,音频开始在后台播放。但是,在向视频滑动一次并从视频向前或向后滑动一次之后,音频停止。但在视频的前向或后向查看多个图像后,此问题仍然存在。

我为解决此问题所做的尝试:-

    我尝试使用PagerAdapter 中的playerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() ...) 方法在视图之间滑动时处理播放器状态。不幸的是,我无法掌握使用不同的播放器状态。 我还尝试在StatusViewer 类中使用viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() ... 方法。

StatusViewerJava 类(在ViewPager 中设置PagerAdapter 类对象):-

modelFeedArrayList = (ArrayList<File>) getIntent().getSerializableExtra("modelFeedArrayList");
position = intent.getIntExtra("position", 0);
ImageSlideAdapter imageSlideAdapter = new ImageSlideAdapter(this,modelFeedArrayList,position);
viewPager.setAdapter(imageSlideAdapter);
viewPager.setCurrentItem(position);
viewPager.setOffscreenPageLimit(0);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() 
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 

        

        @Override
        public void onPageSelected(int position) 

            File currentFile = modelFeedArrayList.get(position);
            String filePath = currentFile.toString();
            if (filePath.endsWith(".jpg") || currentPage == position)
                currentPage = position;
                ImageSlideAdapter.player.pause();
            
            else 
                currentPage = position;
                ImageSlideAdapter.player.play();
            

        

        @Override
        public void onPageScrollStateChanged(int state) 

        
    );

ImageSliderAdapter (PagerAdapter)(下面提到的代码在instantiateItem里面):-

File currentFile = modelFeedArrayList.get(position);
String filePath = currentFile.toString();

if (currentFile.getAbsolutePath().endsWith(".mp4")) 
    statusImageView.setVisibility(View.GONE);
    playerView.setVisibility(View.VISIBLE);

    player = new ExoPlayer.Builder(context).build();

    MediaItem mediaItem = MediaItem.fromUri(filePath);
    player.addMediaItem(mediaItem);

    playerView.setPlayer(player);
    player.prepare();
    playerView.setBackgroundColor(context.getResources().getColor(android.R.color.black));

        playerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() 
            @Override
            public void onViewAttachedToWindow(View v) 

                Log.d("Filepath", filePath);
                Log.d("Position", "" + position);
            

            @Override
            public void onViewDetachedFromWindow(View v) 

                if (filePath.endsWith(".jpg") || currentPage == position || modelFeedArrayList.get(currentPage).getAbsolutePath().endsWith(".jpg"))
                    currentPage = position;
                    player.pause();
                    Objects.requireNonNull(playerView.getPlayer()).pause();
                
                else 
                    player.release();
                    Objects.requireNonNull(playerView.getPlayer()).release();
                
            
        );


     else 
        playerView.setVisibility(View.GONE);
        statusImageView.setVisibility(View.VISIBLE);
        Glide.with(context).load(modelFeedArrayList.get(position)).into(statusImageView);

        statusImageView.setBackgroundColor(context.getResources().getColor(android.R.color.black));
    

    Objects.requireNonNull(container).addView(itemView);

    return itemView;


@Override
public void destroyItem(@NonNull @NotNull ViewGroup container, int position, @NonNull @NotNull Object object) 

    container.removeView((ConstraintLayout) object);

【问题讨论】:

请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。 【参考方案1】:

感谢 *** 社区查看此问题。我通过下面提到的修改解决了上述问题:-

    ImageSliderAdapter (PagerAdapter) 的变化:-

-> 下面提到的代码被添加到onViewAttachedToWindow(View v):-

if (filePath.endsWith(".jpg") || currentPage == position || modelFeedArrayList.get(currentPage).getAbsolutePath().endsWith(".jpg"))
     currentPage = position;
     player.pause();
     Objects.requireNonNull(playerView.getPlayer()).pause();

else 
     player.pause();
     Objects.requireNonNull(playerView.getPlayer()).pause();
     if (filePath.endsWith(".mp4"))
          player.pause();
          Objects.requireNonNull(playerView.getPlayer()).pause();
     
     else 
          player.play();
          Objects.requireNonNull(playerView.getPlayer()).play();
     

-> 下面提到的代码是在onViewDetachedFromWindow(View v) 中添加的:-

if (filePath.endsWith(".mp4"))
     player.release();
     Objects.requireNonNull(playerView.getPlayer()).release();

-> player.play() 是在player.prepare() 之后添加的。

    StatusViewer Java 类的变化:-

-> 以下更改修复了播放器故障以及播放器的play 状态和release 状态的问题。我在setCurrentItem中使用了smoothScroll: false

    viewPager.setCurrentItem(position,false);

【讨论】:

以上是关于PagerAdapter 总是在 ViewPager 中被调用两次的主要内容,如果未能解决你的问题,请参考以下文章

PagerAdapter 总是在 ViewPager 中被调用两次

PagerAdapter相关

如何在 PagerAdapter 中返回多个片段(不是 FragmentPagerAdapter)

PagerAdapter 中的异步位置

PagerAdapter 的问题

Android setVisibility无法在PagerAdapter中运行