正在停止外观扫视器的ViewPager

问题描述:

我正在使用ViewPager单片段实例,其中我显示Media文件,如图像,视频,音频。正在停止外观扫视器的ViewPager

我实施了ExoPlayer进行处理Video & Audio文件。和Glide的图像。

this,以避免内存泄漏我释放ExoPlayer对象像这样ItemViewerFragment.java

private void releasePlayer() { 
     if (player != null) { 
      player.release(); 
      player = null; 
      trackSelector = null; 
      simpleExoPlayerView.setPlayer(null); 
     } 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     if (player == null && currentGalleryModel != null) { 
      initializePlayer(); 
     } 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (player == null && currentGalleryModel != null) { 
      initializePlayer(); 
     } 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     releasePlayer(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     releasePlayer(); 
    } 

而在onViewCreated()我初始化看法是这样的:

@Override 
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 

     if (currentGalleryModel.isVideo() || currentGalleryModel.isAudio()) { 

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

      initializePlayer(); 
     } else if (currentGalleryModel.isImage() || currentGalleryModel.isGif()) { 
      simpleExoPlayerView.setVisibility(View.GONE); 
      imageView.setVisibility(View.VISIBLE); 


      Glide.with(this) 
        .load(currentGalleryModel.getFilePath()) 
        .placeholder(android.R.color.black) 
        .fitCenter() 
        .diskCacheStrategy(DiskCacheStrategy.NONE) 
        .into(imageView); 

     } 
    } 

我使用FragmentStatePagerAdapeter 。这是getItem方法:

@Override 
public Fragment getItem(int position) { 
    return ItemViewerFragment.newInstance(mItems.get(position)); 
} 

我不能够检测片段的上的Viewpager先刷卡。在第二次滑动video/audio文件停止播放。

在活动我曾尝试加入.addOnPageChangeListener

@Override 
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

    try { 
     ((ItemViewerFragment)mAdapter.getItem(mPreviousPos)).imHiddenNow(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     mPreviousPos = position; 
    } 

而且在ItemViewerFragment.java

public void imHiddenNow(){ 
     releasePlayer(); 
    } 

不过video/audio不断播放。

这是Screencast的Video Link

Demo project GitHub link

请注意,下面发布的解决方案不起作用

+0

过得好在onScrollListener以前的位置? –

+0

另外我看到getItem方法每次都会返回一个newInstance,这可能是原因。 –

+0

初始化时,我正在显示正在显示的'GalleryModel'的当前位置。因此,假设我在我的列表中有30个项目,并且显示第5个项目。然后'onScroll'上的位置将是第5位,当前位置将是第4或第6位,具体取决于它在哪一侧滚动。 –

下面是寻呼机适配器代码:

class ViewPagerAdapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragmentList = new ArrayList<>(); 
    private final List<String> mFragmentTitleList = new ArrayList<>(); 

    public ViewPagerAdapter(FragmentManager manager) { 
     super(manager); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragmentList.get(position); 
    } 

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

    public void addFragment(Fragment fragment, String title) { 
     mFragmentList.add(fragment); 
     mFragmentTitleList.add(title); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mFragmentTitleList.get(position); 
    } 
} 

这里是滚动监听器:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      //Stop media here. 
     } 

     @Override 
     public void onPageSelected(int position) { 
      //Save your previous position here. 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 
    }); 

对于媒体你可以使用一个for循环,所有的片段添加到列表然后用它来提高效率:

viewPager.setOffscreenPageLimit(3); 

这将确保只有3个实例r片段可用,这是足够的。

对于使用单一片段,我会建议你做这样的:

public MyFragment() { 

} 

//This is to send a file to the fragment if you need it. 
public static MyFragment newInstance(File file) { 
    MyFragment fragment = new MyFragment(); 
    Bundle bundle = new Bundle(); 
    bundle.putSerializable("file", file); 
    fragment.setArguments(bundle); 
    return fragment; 
} 

然后在片段你的OnCreate可以检索你的文件是这样的:

File file; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    file = getArguments().getSerializable("file"); 

} 

现在添加您的片段寻呼机是这样的:

for (int i = 0; i < totalFiles; i++) { 
      viewPagerAdapter.addFragment(MyFragment.newInstance(fileList.get(i)); 
     } 

希望这有助于。

+0

好吧,我会尝试。谢谢! –

+0

假设我有1000个媒体文件。它会创建1000个碎片? 'mFragmentList'会是这么大? –

+0

你现在如何管理列表? –

自从我使用Exoplayer &以来已经有一年多的时间了,我还有点类似的问题。请注意API已经发生了一些变化,因此请采取以下代码来了解如何实施潜在解决方案。请让我知道,如果它不起作用,我会进一步调查API并回复你。

来到了解决方案:

private int mPlayerCurrentPosition; 

private int getCurrentPlayerPosition() { 
    return mExoPlayer.getCurrentPosition(); 
} 

// call this from onPause 
private void releaseExoplayer() { 
    mPlayerCurrentPosition = getPlayerCurrentPosition(); 
    mExoPlayer.setPlayWhenReady(false); 
    mExoPlayer.release(); // this will make the player object eligible for GC 
} 

private void resumePlaybackFromPreviousPosition(int prevPosition) { 
    mExoPlayer.seekTo(mPlayerCurrentPosition); 
} 
+0

谢谢!行为是一样的。我想在第二次滑动时第一次滑动“viewPager”时暂停播放器。 –

+0

您是否尝试调用releaseExoplayer()中提到的onPageScrolled和onPageScrollStateChanged回调为viewPager回答? –

+0

是的,我做过了。尽管'onSwipe'当前的片段正在停止播放器。 'onSwipeBack'到相同的片段不会恢复播放器。我在片段 –