在Android ViewPager中滑动时发布媒体播放器

6

背景: 我有一个活动,4个片段和一个视图页面(每个页面包含一个片段)。每个片段都包含一组短声音(每个声音最多5秒)。期望的行为是:如果用户在某个页面上单击了一个声音,并且该声音没有播放完毕,如果用户滑动到另一页,则媒体播放器将被释放,因此声音将停止播放。

问题: 当向左或向右滑动时,onPause或onStop方法不会被调用(因为viewPager根据定义加载当前页,前一页和下一页),因此播放来自最后一页的媒体播放器不会在滑动时停止。

研究: 我在多个帖子上进行了大量搜索,涉及到onPageChangeListenersetOffScreenPageLimit,将MediaPlayer设置为活动而不是片段(在我的情况下不可能,因为我有适配器中的声音列表)。这里是我研究但没有解决问题的一些链接:ViewPager swipe previous soundMultiple video players in viewpager in androidAndroid MediaPlayer on ViewPager blocking UI transition and no callback for initial page loadsHow to handle MediaPlayer object inside a fragment inside view pagerUsing Viewpager with MediaPlayer

你有建议吗?: 如果您对如何解决此问题有任何建议,将不胜感激!谢谢!

3个回答

3
您可以在您的MainActivity上创建一个Callback接口,其中包含一个onPageChanged()方法,如下所示:
public interface Callback {
    void onPageChanged();
}

接下来,你可以使用这个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) {
    }
});

您的ViewPager中的每个Fragment都可以按照以下方式创建:

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

完成这个步骤后,每当您在ViewPager上更改Fragment时,它都将调用前一个Fragment上的onPageChanged方法,在那里您可以释放您的媒体播放器并执行任何其他所需操作。


1
考虑将片段本身作为 OnPageChangeListener。然后,当您附加页面时,可以设置侦听器。这将允许您将页面更改信息传递给片段。您可以拥有多个 OnPageChangeListener。希望这可以帮助您。

编辑:

考虑类似于此的东西。

public class PageFragment extends Fragment implements ViewPager.OnPageChangeListener {
    ViewPager pager;

    public void onPageScrollStateChanged (int state){
         // reset the player if needed. you can do this since player object is in this class
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ....
        pager = (ViewPager) getActivity().findViewById(ViewPagerId);
        pager.addOnPageChangeListener(this);
        ....
    }
    @Override
    public void onDestroyView (){
        ....
        pager.removeOnPageChangeListener(this);
        ....

    }
}

你说“当你附加页面时,可以设置监听器”,但我的4个页面(4个片段)都是通过适配器添加的。你能否提供一个代码片段来澄清你的建议? - George Radu
2
不幸的是它不起作用。我在片段中使用了implements ViewPager.OnPageChangeListener,但方法没有被触发... - George Radu

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

全局变量
我遇到了同样的问题。在片段中,我有两个方法play和stop,并在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();

Dheerubhai Bansal,以上代码解决了您的问题吗?或者使用它后,您仍然遇到了问题? - George Radu
我的问题已经解决了。我现在可以在ViewPager的Fragment中播放视频了。 - D.J
我在Fragment中使用了ViewPager。如果您在Activity中使用ViewPager,请使用getSupportFragmentManager而不是getChildFragmentManager。 - D.J
Dheerubhai,谢谢!我稍微研究了一下你的答案,我试着理解如何在我的情况下将其适应于在活动中使用viewPager(而你在片段中使用它)。另外,我想知道是否可以在上面的代码中不使用第一个“new Thread(new Runnable() {.....}).start()”块来编写。直接进入“try {....} catch (...) {}”不会起作用吗?PS:我已经为你的答案投票了,但我的声望只有1,我刚刚开始使用stackoverflow。 - George Radu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接