Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Releasing media player in Android ViewPager on swipe

Tags:

CONTEXT: I have one activity, 4 fragments and a viewPager (each page consists of one fragment). Each fragment contains a list of short sounds (max 5 seconds each). The expected behavior is: if the user clicks on a sound on a certain page and the sound did not finish playing, if the user swipes to another page, the media player will be released, thus the sound will stop playing.

ISSUE: When swiping left or right, the method onPause or onStop are not called (since the viewPager by definition loads the current, the previous and the next page), thus the media player playing the sound from the last page does not stop on swipe.

RESEARCH: I have searched a lot on multiple posts, related to onPageChangeListener, setOffScreenPageLimit, set MediaPlayer not in fragment but in the activity (not possible in my case, since I have lists of sounds with adapter). Here are some links that I researched but did not solve my problem: ViewPager swipe previous sound, Multiple video players in viewpager in android, Android MediaPlayer on ViewPager blocking UI transition and no callback for initial page loads, How to handle MediaPlayer object inside a fragment inside view pager, Using Viewpager with MediaPlayer

SUGGESTIONS?: if you have any suggestions on how to tackle this issue, it would be highly appreciated! Thanks!

like image 311
George Radu Avatar asked Apr 21 '17 01:04

George Radu


2 Answers

You can create a Callback interface on your MainActivity with a method onPageChanged() like this:

public interface Callback {
    void onPageChanged();
}

Then, you can use this OnPageChangeListener:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

    private int currentPage = 0;

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

    @Override
    public void onPageSelected(int position) {
        Fragment fragment = adapter.getItem(currentPage);

        if (fragment instanceof Callback &&
                currentPage != position) {
            ((Callback)adapter.getItem(currentPage)).onPageChanged();
        }
        currentPage = position;
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});

Each and every Fragment in your ViewPager can be created like this:

public class TestFragment extends Fragment implements MainActivity.Callback {

    private void releaseMediaPlayer() {
        // ...
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // ...
    }

    @Override
    public void onPageChanged() {
        releaseMediaPlayer();
        // You can do more things here
    }
}

After doing that, every time that you change the Fragment on the ViewPager it will be calling the onPageChanged method on the previous Fragment, and in there you can release your media player and do any other operation that you require.

like image 91
Carlos Jimenez Avatar answered Sep 22 '22 11:09

Carlos Jimenez


private int currentPos = 0;
private int prevPos = -1;

global variable

I am getting same problem. I have take two method play and stop in fragment. and call below code in onPageSelected(int position)

new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        prevPos = currentPos;
                        currentPos = position;
                        MyFragment fragment = (MainFragment) getChildFragmentManager().
                                findFragmentByTag("android:switcher:" + R.id.viewPagerVideo + ":" + prevPos);
                        if (fragment != null) {
                            fragment.stop();
                        }
                        fragment = (MyFragment) getChildFragmentManager().
                                findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + currentPos);
                        if (fragment != null) {
                            fragment.play(mListUrl.get(position));
                        }
                    }
                });
            } catch (Exception ignore) {
            }
        }
    }).start();
like image 43
D.J Avatar answered Sep 22 '22 11:09

D.J