停止Exoplayer onSwipe of ViewPager

Nil*_*kar 15 java android android-viewpager exoplayer

我正在使用ViewPager单片段实例,其中我显示Media图像,视频,音频等文件.

我已经实现ExoPlayer了处理VideoAudio文件.而Glide对于图像.

这里避免内存泄漏我发布这样的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();
    }
Run Code Online (Sandbox Code Playgroud)

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);

        }
    }
Run Code Online (Sandbox Code Playgroud)

我在用FragmentStatePagerAdapeter.这是getItem方法:

@Override
public Fragment getItem(int position) {
    return ItemViewerFragment.newInstance(mItems.get(position));
}
Run Code Online (Sandbox Code Playgroud)

我无法onPause在第一次扫描时检测到碎片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;
    }
Run Code Online (Sandbox Code Playgroud)

并在ItemViewerFragment.java:

public void imHiddenNow(){
      releasePlayer();
    }
Run Code Online (Sandbox Code Playgroud)

仍在video/audio继续比赛.

这是Screencast 的视频链接.

演示项目GitHub链接.

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

Nil*_*kar 6

我遵循了一种在HashMap内部维护片段对象的方法PagerAdapter

  1. 声明一个接口:
interface FragmentLifecycle {
    void onPauseFragment()
}
Run Code Online (Sandbox Code Playgroud)
  1. 在 Fragment 中实现一个接口。
public void onPauseFragment() {
    if (simpleExoPlayer != null){
        simpleExoPlayer.setPlayWhenReady(false);
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 将所有片段对象存储在 a 中,HashMap<Integer,Fragment>并将各自的位置作为键。在里面声明hashmap PagerAdapter。还声明一种用于从 hashmap 访问片段对象的 getter 方法。例如

    @Override
    public Fragment getItem(int position) {
        ItemViewerFragment fragment = ItemViewerFragment.newInstance(mItems.get(position));
        mFragments.put(position,fragment);
        return fragment;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    公共 ItemViewerFragment getMapItem(int position) { return mFragments.get(position); }

  2. 在您声明viewPagerkeep 一个变量currentPosition并实施的活动中ViewPager.OnPageChangeListener

  3. 内部onPageSelected方法,

        @Override
        public void onPageSelected(int position) {
            if(mAdapter.getMapItem(currentPosition) != null) (mAdapter.getMapItem(currentPosition)).onPauseFragment();
            currentPosition = position;
        }
    
    Run Code Online (Sandbox Code Playgroud)


Sar*_*dhi 5

从未来进行编辑:您永远不应该直接在 FragmentPagerAdapter 内保存对 Fragment 实例的引用,因为它可能会在进程死亡后导致崩溃。

这是寻呼机适配器的代码:

 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是滚动侦​​听器:

  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) {
         
        }
    });
Run Code Online (Sandbox Code Playgroud)

对于媒体,您可以使用 for 循环并将所有片段一次添加到列表中,然后使用它来提高效率:

viewPager.setOffscreenPageLimit(3);
Run Code Online (Sandbox Code Playgroud)

这将确保您的片段只有 3 个实例可用,这已经足够了。

对于使用单个片段,我建议您这样做:

 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;
}
Run Code Online (Sandbox Code Playgroud)

然后在 Fragment 的 onCreate 中,您可以像这样检索文件:

File file;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    file = getArguments().getSerializable("file");
   
}
Run Code Online (Sandbox Code Playgroud)

现在将片段添加到寻呼机,如下所示:

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

希望这可以帮助。