Android 使用ViewPager进行屏幕旋转-FragmentManager和FragmentPagerAdapter出现问题

Android 使用ViewPager进行屏幕旋转-FragmentManager和FragmentPagerAdapter出现问题,android,android-fragments,Android,Android Fragments,我在使用ViewPager处理片段时遇到一些问题 我吃的东西: 一种活动(例如,MainActivity),它包含一个ViewPager,用于显示某些片段。其中一些包含回调接口,将调用该接口在MainActivity中执行某些操作 main活动有一个FragmentPagerAdapter类,它用作ViewPager的适配器。以及片段页面编辑器中的列表,用于存储将显示在查看页面上的片段 我所期待的: 第一次启动时,当我按下回调接口中的按钮时,片段调用了回调接口的方法,MainActivity在其

我在使用ViewPager处理片段时遇到一些问题

我吃的东西:
一种活动(例如,
MainActivity
),它包含一个
ViewPager
,用于显示某些片段。其中一些包含回调接口,将调用该接口在
MainActivity
中执行某些操作
main活动
有一个
FragmentPagerAdapter
类,它用作
ViewPager
的适配器。以及
片段页面编辑器
中的
列表
,用于存储将显示在
查看页面
上的片段

我所期待的:
第一次启动时,当我按下回调接口中的按钮时,片段调用了回调接口的方法,MainActivity在其中做了一些事情。效果很好。
在屏幕旋转之后,我希望它的工作原理与第一次启动时一样,但是
NullPointerException:试图调用null引用对象(特别是片段的接口)上的方法,这让我大吃一惊

我所知道的:
-创建片段后,将不再调用
getItem(int位置)
。相反,将调用
实例化项(视图组容器,int位置)

-
FragmentManager
将在
mActive.mValues
中存储一些片段
-(我也提到了这一点和其他一些关于StackOverflow的相同主题。)

我所尝试和看到的:
-覆盖实例化项(视图组容器,int位置)
-调试了1天。我看到,当我将MainActivity的
onCreate()
方法中的
getSupportFragmentManager()
传递给
FragmentPagerAdapter
的超级构造函数时,在第一次启动时,它有一个“内存中的地址”,假设它是“1A1”。
FragmentManager
mActive.mValues
保存了一些片段的“内存地址”,这些地址与包含它们的
列表相同(假设是“qwertyu”)。这意味着它是正确的。
但是当我旋转屏幕,再次传递
getSupportFragmentManager()
时,“内存中的地址”完全不同,假设为“9f9f9f9”。和
FragmentManager
mActive.mValues
也包含一组不同的片段“内存地址”(假设'abcdeff'),尽管其中的片段数等于第一次发射时保存的片段数(旋转前)。
我在
列表中添加了一个片段,其中包含一个新的“内存地址”(假设为'ababababa'),具有回调接口。但是,当我点击其中的按钮时,旋转后,
FragmentManager
mActive.mValues
中的片段(如我上面所假设的,“内存中的地址”是'abcdeff'),并且该片段没有回调接口(因为没有首先在
MainActivity
中设置)。并导致如上所述的NullPointerException

我现在的问题是:
-首先,如何解决这个问题!?最好继续使用
FragmentPagerAdapter
而不是另一个类。但我也会考虑使用其他课程。 -第二,你能解释一下为什么
FragmentManager
在旋转之前保存了片段实例吗。但在旋转之后,它创建了一个完全不同的片段实例,但仍然使用它来代替保存在
列表中的片段

下面是代码(我想我没有以正确的方式使用
实例化Item(ViewGroup容器,int position)
方法,所以它仍然会导致问题)

public类MainActivity扩展了AppCompatActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//将SectionsPagerAdapter连接到ViewPager
SectionsPagerAdapter pagerAdapter=新SectionsPagerAdapter(getSupportFragmentManager());
ViewPager ViewPager=findViewById(R.id.ViewPager);
viewPager.setAdapter(pagerAdapter);
}
//
//
//适配器类
私有类SectionsPagerAdapter扩展了FragmentPagerAdapter{
私有静态最终整型页面_HOME=0;
私有int tabCount=1;
私有列表fragmentList=新的ArrayList();
private List fragmentTitleList=新建ArrayList();
//私人碎片管理器碎片管理器;
SectionsPagerAdapter(碎片管理器fm){
超级(fm);
//碎片管理器=fm;
//默认HomeFragment
HomeFragment HomeFragment=新的HomeFragment();
//回调接口
setOnCategoryFragmentChangedListener(新的homeFragment.OnCategoryFragmentChangedListener(){
//单击HomeFragment中的按钮时将调用此方法
@凌驾
onAddNewCategory(字符串categoryName)上的公共void{
addNewCategory(categoryName);
}
});
碎片列表。添加(homeFragment);
碎片标题列表。添加(“主页”);
}
@凌驾
公共片段getItem(int位置){
返回碎片列表。获取(位置);
}
@凌驾
public int getCount(){
返回tabCount;
}
@凌驾
公共字符序列getPageTitle(int位置){
返回碎片标题列表。获取(位置);
}
@凌驾
公共对象实例化项(视图组容器,int位置){
fragmentList.set(position,(Fragment)super.instanceItem(container,position));
返回碎片列表。获取(位置);
}
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Attach the SectionsPagerAdapter to the ViewPager
        SectionsPagerAdapter pagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.viewPager);
        viewPager.setAdapter(pagerAdapter);
    }


    //
    //
    //Adapter class
    private class SectionsPagerAdapter extends FragmentPagerAdapter {
        private static final int PAGE_HOME = 0;
        private int tabCount = 1;
        private List<Fragment> fragmentList = new ArrayList<>();
        private List<String> fragmentTitleList = new ArrayList<>();
        //private FragmentManager fragmentManager;

        SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
            //fragmentManager = fm;

            //Default HomeFragment
            HomeFragment homeFragment = new HomeFragment();
            //Callback interface
            homeFragment.setOnCategoryFragmentChangedListener(new HomeFragment.OnCategoryFragmentChangedListener() {
                //This method will be called when a button in HomeFragment is clicked
                @Override
                public void onAddNewCategory(String categoryName) {
                    addNewCategory(categoryName);
                }
            });
            fragmentList.add(homeFragment);
            fragmentTitleList.add("Home");
        }

        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }

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

        @Override
        public CharSequence getPageTitle(int position) {
            return fragmentTitleList.get(position);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            fragmentList.set(position, (Fragment) super.instantiateItem(container, position));
            return fragmentList.get(position);
        }

        private void addNewCategory(String categoryName) {
            CategoryFragment fragment = new CategoryFragment();

            tabCount += 1;
            fragmentList.add(fragment);
            fragmentTitleList.add(categoryName);
            notifyDataSetChanged();
        }
    }
}
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            fragmentList.set(position, (Fragment) super.instantiateItem(container, position));
            Fragment fragment = fragmentList.get(position);
            if (position == PAGE_HOME) {
                ((HomeFragment) fragment).setOnCategoryFragmentChangedListener(new HomeFragment.OnCategoryFragmentChangedListener() {
                    @Override
                    public void onAddNewCategory(String categoryName) {
                        addNewCategory(categoryName);
                    }
                });
            }
            return fragment;
        }