【问题标题】:How to call method on Fragment from ViewPager?如何从 ViewPager 调用 Fragment 上的方法?
【发布时间】:2017-10-14 00:40:47
【问题描述】:

我有 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,

再次OpenTextFragment 在位置 3 等等...

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      相关资源
      最近更新 更多