Android - 具有动态标签数量的 tabbedActivity
Android - tabbedActivity with dynamic number of tabs
我正在创建一个应用程序,它(根据选择的模式)必须在选项卡式 activity 中有 2 个或 3 个选项卡。当我选择带有三个选项卡的模式时,一切都很好,但是需要 2 个选项卡的模式会引发此异常:
java.lang.IllegalStateException: The application's PagerAdapter
changed the adapter's contents without calling
PagerAdapter#notifyDataSetChanged! Expected adapter item count: 3,
found: 2 Pager id: abm.ant8.sotgtests:id/container Pager class: class
android.support.v4.view.ViewPager Problematic adapter: class
abm.ant8.sotgtests.MainActivity$SectionsPagerAdapter
当我注释掉 this.notifyDataSetChanged()(标记为此处)时,它在两种情况下都崩溃了。这是我的 PagerAdapter 代码(我使用的是 v4 支持包):
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
mExplanationFragment = ExplanationFragment.newInstance();
mQuestionFragment = QuestionFragment.newInstance(totalNoOfQuestions);
if (mode == LEARNING_MODE) {
mRulesFragment = RulesFragment.newInstance();
}
Fragment fragment;
if (mode == TESTING_MODE) {
if (position == 1) {
fragment = mExplanationFragment;
} else {
fragment = mQuestionFragment;
}
} else {
if (position == 2) {
fragment = mExplanationFragment;
} else if (position == 1){
fragment = mQuestionFragment;
} else {
fragment = mRulesFragment;
}
}
//this.notifyDataSetChanged(); HERE
return fragment;
}
@Override
public int getCount() {
if (mode == TESTING_MODE) {
return 2;
} else {
return 3;
}
}
//...
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
}
这已经是在应用 this SO topic 的提示之后,其他看起来非常相似。对于这种情况,这种方法(直接取自 Android Studio 向导)是否完全正确?看起来将默认开始选项卡定义为中间而不是第一个也会很麻烦(但这当然是另一个问题,在我解决了这个问题之后)。
编辑:作为一个强力解决方案,我正在考虑简单地复制当前的 Activity 并稍微修改它,这样它就不会是一个 Activity意图,而不是调用不同的活动。由于大部分所需的功能已经实现(其中大部分是片段),这绝对是最快的方法。为了保持模块化和干净,我可以做一些重构并将两个 Activity 通用的方法移动到单独的 class.
我最终创建了两个单独的适配器,在托管中调用它们 Activity:
if (mode == LEARNING_MODE) {
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(1);
} else {
mTwoSectionsPagerAdapter = new TwoSectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mTwoSectionsPagerAdapter);
}
所以这些 PagerAdapter 只是 getCount()
不同,当然还有在各自的位置提供适当的片段(getItem()
方法)。
我正在创建一个应用程序,它(根据选择的模式)必须在选项卡式 activity 中有 2 个或 3 个选项卡。当我选择带有三个选项卡的模式时,一切都很好,但是需要 2 个选项卡的模式会引发此异常:
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 3, found: 2 Pager id: abm.ant8.sotgtests:id/container Pager class: class android.support.v4.view.ViewPager Problematic adapter: class abm.ant8.sotgtests.MainActivity$SectionsPagerAdapter
当我注释掉 this.notifyDataSetChanged()(标记为此处)时,它在两种情况下都崩溃了。这是我的 PagerAdapter 代码(我使用的是 v4 支持包):
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
mExplanationFragment = ExplanationFragment.newInstance();
mQuestionFragment = QuestionFragment.newInstance(totalNoOfQuestions);
if (mode == LEARNING_MODE) {
mRulesFragment = RulesFragment.newInstance();
}
Fragment fragment;
if (mode == TESTING_MODE) {
if (position == 1) {
fragment = mExplanationFragment;
} else {
fragment = mQuestionFragment;
}
} else {
if (position == 2) {
fragment = mExplanationFragment;
} else if (position == 1){
fragment = mQuestionFragment;
} else {
fragment = mRulesFragment;
}
}
//this.notifyDataSetChanged(); HERE
return fragment;
}
@Override
public int getCount() {
if (mode == TESTING_MODE) {
return 2;
} else {
return 3;
}
}
//...
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
}
这已经是在应用 this SO topic 的提示之后,其他看起来非常相似。对于这种情况,这种方法(直接取自 Android Studio 向导)是否完全正确?看起来将默认开始选项卡定义为中间而不是第一个也会很麻烦(但这当然是另一个问题,在我解决了这个问题之后)。
编辑:作为一个强力解决方案,我正在考虑简单地复制当前的 Activity 并稍微修改它,这样它就不会是一个 Activity意图,而不是调用不同的活动。由于大部分所需的功能已经实现(其中大部分是片段),这绝对是最快的方法。为了保持模块化和干净,我可以做一些重构并将两个 Activity 通用的方法移动到单独的 class.
我最终创建了两个单独的适配器,在托管中调用它们 Activity:
if (mode == LEARNING_MODE) {
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(1);
} else {
mTwoSectionsPagerAdapter = new TwoSectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mTwoSectionsPagerAdapter);
}
所以这些 PagerAdapter 只是 getCount()
不同,当然还有在各自的位置提供适当的片段(getItem()
方法)。