ViewPager and fragments — what's the right way to store fragment's state?

后端 未结 11 1344
遇见更好的自我
遇见更好的自我 2020-11-22 02:21

Fragments seem to be very nice for separation of UI logic into some modules. But along with ViewPager its lifecycle is still misty to me. So Guru thoughts are b

11条回答
  •  难免孤独
    2020-11-22 02:44

    To get the fragments after orientation change you have to use the .getTag().

        getSupportFragmentManager().findFragmentByTag("android:switcher:" + viewPagerId + ":" + positionOfItemInViewPager)
    

    For a bit more handling i wrote my own ArrayList for my PageAdapter to get the fragment by viewPagerId and the FragmentClass at any Position:

    public class MyPageAdapter extends FragmentPagerAdapter implements Serializable {
    private final String logTAG = MyPageAdapter.class.getName() + ".";
    
    private ArrayList fragmentPages;
    
    public MyPageAdapter(FragmentManager fm, ArrayList fragments) {
        super(fm);
        fragmentPages = fragments;
    }
    
    @Override
    public Fragment getItem(int position) {
        return this.fragmentPages.get(position).getFragment();
    }
    
    @Override
    public CharSequence getPageTitle(int position) {
        return this.fragmentPages.get(position).getPageTitle();
    }
    
    @Override
    public int getCount() {
        return this.fragmentPages.size();
    }
    
    
    public int getItemPosition(Object object) {
        //benötigt, damit bei notifyDataSetChanged alle Fragemnts refrehsed werden
    
        Log.d(logTAG, object.getClass().getName());
        return POSITION_NONE;
    }
    
    public Fragment getFragment(int position) {
        return getItem(position);
    }
    
    public String getTag(int position, int viewPagerId) {
        //getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.shares_detail_activity_viewpager + ":" + myViewPager.getCurrentItem())
    
        return "android:switcher:" + viewPagerId + ":" + position;
    }
    
    public MyPageBuilder getPageBuilder(String pageTitle, int icon, int selectedIcon, Fragment frag) {
        return new MyPageBuilder(pageTitle, icon, selectedIcon, frag);
    }
    
    
    public static class MyPageBuilder {
    
        private Fragment fragment;
    
        public Fragment getFragment() {
            return fragment;
        }
    
        public void setFragment(Fragment fragment) {
            this.fragment = fragment;
        }
    
        private String pageTitle;
    
        public String getPageTitle() {
            return pageTitle;
        }
    
        public void setPageTitle(String pageTitle) {
            this.pageTitle = pageTitle;
        }
    
        private int icon;
    
        public int getIconUnselected() {
            return icon;
        }
    
        public void setIconUnselected(int iconUnselected) {
            this.icon = iconUnselected;
        }
    
        private int iconSelected;
    
        public int getIconSelected() {
            return iconSelected;
        }
    
        public void setIconSelected(int iconSelected) {
            this.iconSelected = iconSelected;
        }
    
        public MyPageBuilder(String pageTitle, int icon, int selectedIcon, Fragment frag) {
            this.pageTitle = pageTitle;
            this.icon = icon;
            this.iconSelected = selectedIcon;
            this.fragment = frag;
        }
    }
    
    public static class MyPageArrayList extends ArrayList {
        private final String logTAG = MyPageArrayList.class.getName() + ".";
    
        public MyPageBuilder get(Class cls) {
            // Fragment über FragmentClass holen
            for (MyPageBuilder item : this) {
                if (item.fragment.getClass().getName().equalsIgnoreCase(cls.getName())) {
                    return super.get(indexOf(item));
                }
            }
            return null;
        }
    
        public String getTag(int viewPagerId, Class cls) {
            // Tag des Fragment unabhängig vom State z.B. nach bei Orientation change
            for (MyPageBuilder item : this) {
                if (item.fragment.getClass().getName().equalsIgnoreCase(cls.getName())) {
                    return "android:switcher:" + viewPagerId + ":" + indexOf(item);
                }
            }
            return null;
        }
    }
    

    So just create a MyPageArrayList with the fragments:

        myFragPages = new MyPageAdapter.MyPageArrayList();
    
        myFragPages.add(new MyPageAdapter.MyPageBuilder(
                getString(R.string.widget_config_data_frag),
                R.drawable.ic_sd_storage_24dp,
                R.drawable.ic_sd_storage_selected_24dp,
                new WidgetDataFrag()));
    
        myFragPages.add(new MyPageAdapter.MyPageBuilder(
                getString(R.string.widget_config_color_frag),
                R.drawable.ic_color_24dp,
                R.drawable.ic_color_selected_24dp,
                new WidgetColorFrag()));
    
        myFragPages.add(new MyPageAdapter.MyPageBuilder(
                getString(R.string.widget_config_textsize_frag),
                R.drawable.ic_settings_widget_24dp,
                R.drawable.ic_settings_selected_24dp,
                new WidgetTextSizeFrag()));
    

    and add them to the viewPager:

        mAdapter = new MyPageAdapter(getSupportFragmentManager(), myFragPages);
        myViewPager.setAdapter(mAdapter);
    

    after this you can get after orientation change the correct fragment by using its class:

            WidgetDataFrag dataFragment = (WidgetDataFrag) getSupportFragmentManager()
                .findFragmentByTag(myFragPages.getTag(myViewPager.getId(), WidgetDataFrag.class));
    

提交回复
热议问题