2017-10-11 9 views
8

ViewPager私はMedia Images、Videos、Audioのようなファイルを表示しているシングル・フラグメント・インスタンスで使用しています。ExplayerをViewPagerのスワイプで停止する

Video & Audioファイルを処理するためにExoPlayerを実装しました。画像の場合はGlideです。私はItemViewerFragment.javaにこのようなExoPlayerオブジェクトを解放していたメモリリークを回避するためにthisから

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を使用しています。

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

私はViewpagerの最初のスワイプにフラグメントのを検出することはできませんよ:これはgetItem方法です。 2回目のスワイプでは、ファイルの再生が停止されます。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位になります。 –

答えて

2

はページャアダプタのコードです:ここで

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

     } 
    }); 

効率を上げるためにこれを使用してください:

viewPager.setOffscreenPageLimit(3); 

これはあなたの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; 
} 

次に断片のの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

あなたは今どのようにリストを管理していますか? –

0

Exoplayer &を使用してから1年以上経ちましたが、同様の問題にちょっとした問題がありました。 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

ありがとう!行動は同じです。 2回目のスワイプで起こっている 'viewPager'の最初のスワイプでプレイヤーを一時停止したいと思います。 –

+0

viewPagerのonPageScrolledコールバックとonPageScrollStateChangedコールバックから、私の答えに記載されているreleaseExplayer()を呼び出そうとしましたか? –

+0

はい、私はしました。「onSwipe」の現在の断片がプレイヤーを止めていても。同じフラグメントへの 'onSwipeBack'はPlayerを再開しません。フラグメントの 'onResume'で' resumePlaybackFromPreviousPosition'を呼び出しています –

関連する問題