ViewPager和FragmentPagerAdapter:如何通知片段实例它正在切换到另一个片段?

时间:2016-06-27 13:13:16

标签: android android-fragments

我有一个ViewPagerFragmentPagerAdapter和一些片段。当用户切换到另一个时,我需要通知片段(以便第一个可以完成其工作)。我正在调查ViewPager.OnPageChangeListener,但在发生更改时无法看到任何获取当前片段实例的方法。在ViewPager.getCurrentItem()被调用时,即使OnPageChangeListener.onPageSelected也会返回新位置。

每次选择新片段时,是否可以保证为前一个片段调用Fragment.onPause()?这肯定会简化事情。

4 个答案:

答案 0 :(得分:1)

根据文档似乎onPause在用户离开片段时会调用(尽管并不总是意味着片段被破坏)。

https://developer.android.com/guide/components/fragments.html

答案 1 :(得分:0)

您可以在类级别保留片段的引用,如mCustomFragment。 然后在你的片段中设置一个公共方法,它将完成工作,只需在ViewPager.OnPageChangeListener中需要时调用此方法。

答案 2 :(得分:0)

也许附上某种手势监听器来确定滑动发生的方式。然后基于调用之前使用的最后一个手势在OnPageChangeListener上,确定是否在当前viewpager索引上放置+1或-1。

答案 3 :(得分:0)

这是我真正有效的解决方案。它涉及广播以通知片段。

首先,我扩展了Fragment类:

@SuppressLint("ValidFragment")
public class ExtendedFragment extends Fragment {

    public static final String FragmentIdTag = "Fragment ID";
    public static final String FragmentSwitchedEventId = "FragmentSwitchedEvent";

    @SuppressLint("ValidFragment")
    protected ExtendedFragment(FragmentType fragmentId) {
        m_fragmentType = fragmentId;
    }

    public void onSwitchedAway() {
    }

    public BroadcastReceiver broadcastReceiver() {
        return m_receiver;
    }

    class Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            FragmentType newFragmentType = (FragmentType) intent.getSerializableExtra(FragmentIdTag);
            if (newFragmentType != m_fragmentType)
                onSwitchedAway();
        }
    }

    protected final FragmentType m_fragmentType;
    Receiver m_receiver = new Receiver();
}

FragmentTypeenum,每个片段都不同。所有片段都扩展ExtendedFragment(一个可怕的名字,我知道。随意建议一个更好的名称)并将适当的唯一FragmentType值传递给它的构造函数。

然后我使用Viewpager.OnPageChangeListener来检测片段开关:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

            @Override
            public void onPageSelected(int position) {
                FragmentType newType = fragmentTypeForPosition(position);
                Intent i = new Intent(ExtendedFragment.FragmentSwitchedEventId);
                i.putExtra(ExtendedFragment.FragmentIdTag, newType);
                LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(i);
            }

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

最后,在实例化片段时不要忘记将它们注册为广播接收器:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                FragmentType newType = fragmentTypeForPosition(position);
                Intent i = new Intent(ExtendedFragment.FragmentSwitchedEventId);
                i.putExtra(ExtendedFragment.FragmentIdTag, newType);
                LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(i);
            }
        });

完成。现在片段可以覆盖public void onSwitchedAway()