【问题标题】:Swipable and replacable tabs, Fragments and ActionBar可滑动和可替换的选项卡、片段和操作栏
【发布时间】:2012-05-05 22:08:08
【问题描述】:

正如主题所述,我正在尝试使用 Fragments 和 ActionBar 实现可滑动的标签。我已经使用 ActionBarSherlock 和 TabsAdapter 类(FragmentPageAdapter 的子类)的示例中的代码成功地实现了它。一些片段应该能够在同一个标​​签spor中显示一个新标签,这就是问题出现的地方。我真的不知道如何用新的片段替换寻呼机中的片段。我用谷歌搜索并尝试了很多东西。

我可以替换在 FragmentPageAdapter 中保存 Fragment 类的内部集合中的 Fragment,从而使新的 Fragment 可用于 getItem 方法,但这并没有这样做,因为我不知道如何将寻呼机更新为显示新的片段。即使在切换到另一个选项卡并返回后,我仍然会得到旧的片段,我认为它正在被寻呼机缓存在某处。那么有没有办法通知寻呼机的更新?

也许我应该忘记使用 FragmentPageAdapter ?在这种情况下,实现所有这些功能的正确方法是什么?

附:如果您想查看我的代码,请告诉我,但它与示例中的基本相同,而且我认为问题更普遍

【问题讨论】:

    标签: android fragment


    【解决方案1】:

    当您使用ViewPager 时,除了您可以导航到的页面/片段之外,它还会将可见页面/片段保留在内存中。除此之外,如果ViewPager 使用FragmentPagerApdapter,它将在活动的生命周期内将视图保存在内存中。

    我在上面删除了可以在此处找到的片段时回答了与您类似的帖子。您的案例是对此的扩展,删除然后添加其他内容。

    https://stackoverflow.com/a/10399127/629555

    基本上,您需要使用FragmentStatePagerAdapter,覆盖getItemPosition 方法以返回PagerAdapter.POSITION_NONE,并确保在您想要更改适配器时调用.notifyDataSetChanged();

    上面链接的答案更详细地介绍了这一点,并提供了一个代码示例。

    【讨论】:

    • 谢谢,我已经尝试过了,它有效!但是使用 FragmentStatePagerAdapter 是否意味着每次我在它们之间切换/滑动时都会重新加载片段,还是它们仍然保存在内存中并在调用 notifyDataSetChanged 时重新加载?
    • FragmentStatePagerAdapter 将在您每次滑动时卸载/加载。它与Fragment 相关的PagerAdapter 在处理能力和内存之间进行权衡。
    • 好的,所以没有办法使用 FragmentPageAdapter 并手动强制重新加载?宁愿这样让它更顺畅。
    • 或者有完全不同的方法吗?一种可能也会使处理后台堆栈更容易的方法?
    • 我想不出使用FragmentPagerAdapter'. I guess you could write your own PagerAdapter`的方法。
    【解决方案2】:

    使用 FragmentStatePagerAdapter 保持对我自己的适配器中的片段的引用怎么样?然后我将它们都保存在内存中,但也可以完全控制删除。这种方法有什么不好的地方吗?以后会遇到问题吗?我也进行了更改,因此片段作为对象而不是类传递,从而将启动留在寻呼机之外。这有什么问题吗?

    附上我的适配器代码:

    public static class TabsAdapter extends FragmentStatePagerAdapter  implements
    ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<Fragment> mTabs = new ArrayList<Fragment>();
    
    
        public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getSupportActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }
    
        public void addTab(ActionBar.Tab tab, Fragment fragment) {          
            tab.setTag(fragment);
            tab.setTabListener(this);
            mTabs.add(fragment);
            mActionBar.addTab(tab);
    
    
            notifyDataSetChanged();
        }           
    
        public void replaceTab(ActionBar.Tab tab, Fragment fragment, int position) {
    
            tab.setTag(fragment);
            tab.setTabListener(this);
            mTabs.set(position, fragment);
            notifyDataSetChanged(); 
        } 
    
        @Override
        public int getCount() {
            return mTabs.size();
        }
    
        @Override
        public Fragment getItem(int position) {
            return mTabs.get(position);
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset,
                int positionOffsetPixels) {
        }
    
        @Override
        public void onPageSelected(int position) {
            mActionBar.setSelectedNavigationItem(position);
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
        }
    
        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            Object tag = tab.getTag();
            for (int i = 0; i < mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }
    
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        }
    
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }
    
        @Override
        public int getItemPosition(Object object){
            return PagerAdapter.POSITION_NONE;
        }
    }
    

    【讨论】:

    • 如果您要向问题添加新信息,您应该编辑您的问题,而不是添加新答案。
    • 我并没有真正将其视为同一个问题。第一个问题要求解决方案,第二个问题是一个解决方案(我想对此作出回应)。
    猜你喜欢
    • 2012-02-20
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    相关资源
    最近更新 更多