我有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
,依此类推......
答案 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;
}