如何从ViewPager调用Fragment上的方法?

时间:2017-10-09 18:21:27

标签: android android-fragments

我有4种类型的片段:     OpenTextFragment, SingleRadioButtonFragment, DropdownSelectFragment and MultipleCheckboxesFragment

这些片段在ViewPager中显示,具体取决于我使用的元素类型。在这些片段中是我需要在MainActivity中使用的特定函数(每个片段都是唯一的)。

ViewPager可以包含N个上面提到的不同片段

我需要什么

我需要获取ViewPager中的当前片段并使用其中的特定函数。

我在做什么

我在ViewPager中显示这些片段的方式是使用FragmentPagerAdapter

public class QuestionsAdapter extends FragmentPagerAdapter {
        private ArrayList<SurveyElement> mSurveyElements;
        private int mAdapterSize = 0;

        public QuestionsAdapter(FragmentManager fm) {
            super(fm);
        }

        public void updateFragmentAdapter(ArrayList<SurveyElement> fragmentList) {
            mSurveyElements = fragmentList;
            mAdapterSize = fragmentList.size();
            this.notifyDataSetChanged();

        }

        @Override
        public Fragment getItem(int position) {
            SurveyElement surveyElement = mSurveyElements.get(position);
            switch (surveyElement.getElementType()) {
                case SurveyElement.OPEN_TEXT:
                    return OpenTextFragment.newInstance(surveyElement, position + 1);
                case SurveyElement.SINGLE_RADIOBUTTON:
                    return  SingleRadioButtonFragment.newInstance(surveyElement, position + 1);
                case SurveyElement.DROPDOWN_SELECT:
                    return DropdownSelectFragment.newInstance(surveyElement, position + 1);
                case SurveyElement.MULTIPLE_CHECKBOXES:
                    return MultipleCheckboxesFragment.newInstance(surveyElement, position + 1);
                default:
                    return OpenTextFragment.newInstance(surveyElement, position + 1);

            }
        }

        @Override
        public int getCount() {
            return mAdapterSize;
        }
    }

我试图在MainAcitivity

中使用此功能获取当前片段
private boolean canIGoToNextQuestion(int position){ // mMyViewPager.getCurrentItem()

        if (mQuestionsAdapter.getItem(position) instanceof OpenTextFragment){
            OpenTextFragment openTextFragment =  (OpenTextFragment) mQuestionsAdapter.getItem(position);
            return openTextFragment.attemptAnswerQuestion();
        }

        // here goes the validations for the others fragments types
        return false;
    }

我喜欢

调用函数attemptAnswerQuestion()时,此函数中的所有元素都是null

好像我正在制作OpenTextFragment的新实例。

好知道

我已经看过几个关于这个主题的帖子,但是他们都知道你的片段的位置,但在我的情况下可以是这样的:

OpenTextFragment可以位于0,

DropdownSelectFragment位置1,

MultipleCheckboxesFragment位置2,

在位置3再次OpenTextFragment,依此类推......

1 个答案:

答案 0 :(得分:0)

在FragmentPagerAdapter中使用instantiateItem()覆盖,以便为ViewPager中已经实例化的片段保留参考。

由于ViewPager中有可变数量的片段,因此使用Map将索引映射到每个片段:

public class QuestionsAdapter extends FragmentPagerAdapter {
    private ArrayList<SurveyElement> mSurveyElements;
    private int mAdapterSize = 0;

    //Fragment container:
    Map<Integer, Fragment> mFragmentMap = new HashMap<>();

    public QuestionsAdapter(FragmentManager fm) {
        super(fm);
    }

    public void updateFragmentAdapter(ArrayList<SurveyElement> fragmentList) {
        mSurveyElements = fragmentList;
        mAdapterSize = fragmentList.size();
        this.notifyDataSetChanged();

    }

    //This populates your Fragment reference map:
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
        mFragmentMap.put(position, createdFragment);
        return createdFragment;
    }

    @Override
    public Fragment getItem(int position) {
        SurveyElement surveyElement = mSurveyElements.get(position);
        switch (surveyElement.getElementType()) {
            case SurveyElement.OPEN_TEXT:
                return OpenTextFragment.newInstance(surveyElement, position + 1);
            case SurveyElement.SINGLE_RADIOBUTTON:
                return  SingleRadioButtonFragment.newInstance(surveyElement, position + 1);
            case SurveyElement.DROPDOWN_SELECT:
                return DropdownSelectFragment.newInstance(surveyElement, position + 1);
            case SurveyElement.MULTIPLE_CHECKBOXES:
                return MultipleCheckboxesFragment.newInstance(surveyElement, position + 1);
            default:
                return OpenTextFragment.newInstance(surveyElement, position + 1);

        }
    }

    @Override
    public int getCount() {
        return mAdapterSize;
    }
}

然后,您可以使用活动中的以下代码为每种类型的片段调用适当的方法。关键是引用在ViewPager中实例化并显示的实际片段:

private boolean canIGoToNextQuestion(int position){ // mMyViewPager.getCurrentItem()

    Fragment fragment = mQuestionsAdapter.mFragmentMap.get(position);
    if (fragment != null && fragment instanceof OpenTextFragment){
        return ((OpenTextFragment)fragment).attemptAnswerQuestion();
    }

    return false;
}