java android android-viewpager exoplayer

java - Detención de Exoplayer onSwipe of ViewPager



android android-viewpager (2)

Estoy usando un ViewPager con instancia de fragmento único en el que estoy mostrando archivos de Media como imágenes, videos, audio.

Implementé ExoPlayer para manejar archivos de Video y Audio . Y Glide por las imágenes.

A partir de esto, para evitar fugas de memoria, estoy liberando el objeto ExoPlayer esta manera en 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(); }

Y en onViewCreated() estoy inicializando una vista como esta:

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

Estoy usando FragmentStatePagerAdapeter . Este es el método getItem :

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

No puedo detectar la onPause del fragmento al primer deslizamiento de Viewpager . En segundo deslizamiento, video/audio archivos de video/audio dejan de reproducirse.

En actividad, intenté agregar .addOnPageChangeListener :

@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { try { ((ItemViewerFragment)mAdapter.getItem(mPreviousPos)).imHiddenNow(); } catch (Exception e) { e.printStackTrace(); } mPreviousPos = position; }

Y en ItemViewerFragment.java :

public void imHiddenNow(){ releasePlayer(); }

El video/audio sigue sonando.

Aquí hay un Video Link al Screencast.

Proyecto de demostración GitHub link .

Tenga en cuenta que la solución publicada a continuación no funciona .


Aquí está el código para el adaptador de buscapersonas:

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

Aquí está el oyente de desplazamiento:

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

Para los medios puede usar un bucle for y agregar todos los fragmentos a la lista de una vez y luego usar esto para la eficiencia:

viewPager.setOffscreenPageLimit(3);

Esto asegurará que solo 3 instancias de tu fragmento estén disponibles, lo cual es suficiente.

Para usar un solo fragmento, te sugiero que lo hagas así:

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

Luego en el onCreate of Fragment puedes recuperar tu archivo de esta manera:

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

Ahora agrega tus fragmentos al buscapersonas de esta manera:

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

Espero que esto ayude.


Ha pasado más de un año desde que utilicé Exoplayer y me enfrenté a un problema similar. Tenga en cuenta que las API han cambiado un poco, así que tome el siguiente código solo para tener una idea de cómo implementar una posible solución. Por favor, avíseme si no funciona, investigaré más las API y le responderé.

Llegando a la solución:

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