Reputation: 1192
I have 4 types of fragments :
OpenTextFragment, SingleRadioButtonFragment, DropdownSelectFragment and MultipleCheckboxesFragment
Those fragments are displaying in the ViewPager depending on the element type that I am using. Inside those fragments are a specific function (unique for each fragment) that I need to use from my MainActivity
.
ViewPager can have N numbers of the different fragments mentioned above
WHAT I NEED
I need to get the current fragment that is in my ViewPager and use that specific function that is in it.
WHAT I AM DOING
The way that I am displaying those fragments in the ViewPager is using a 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;
}
}
I was trying to get the current fragment using this function in 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;
}
I'M STUCK WITH
When the function attemptAnswerQuestion()
is called, all the elements inside this function are null
.
It seems like I'm making a new instance of OpenTextFragment
.
GOOD TO KNOW
I have seen several posts about this topic, but all of them you know the position of your fragments but, in my case can be like:
OpenTextFragment
can be in the position 0,
DropdownSelectFragment
in position 1,
MultipleCheckboxesFragment
position 2,
again OpenTextFragment
in position 3 and so on...
Upvotes: 2
Views: 1278
Reputation: 43322
Use an instantiateItem()
override in the FragmentPagerAdapter in order to keep a reference for the fragments in the ViewPager that have already been instantiated.
Since you have a variable amount of fragments in the ViewPager, use a Map to map the index to each fragment:
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;
}
}
Then, you can use the code below in the activity to call into the appropriate method for each type of fragment. The key is to reference the actual fragment that is instantiated and shown in the 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;
}
Upvotes: 1