viewpager中彻底性动态添加、删除Fragment

viewpager嵌套fragment是一个比较帅气的使用,但是问题多多,毕竟没怎么用过。

之前viewpager的使用顶多是在应用开始的介绍页,viewpager内嵌几张介绍图片,其实这个使用是比较常规的;假如嵌套布局搞的复杂点,如自定义view/fragment,那么就要考虑下布局资源的分发情况了,而不是简单的对Adapter或者pager进行clear、removeAllViews。
拿自己的项目使用情况来说,开始以为viewpager的页数是定的,但最后才知道是动态改变的,不仅可以增加,还要动态的删除!!!这个实时动作真的很折腾,增加是没有问题的,但是减少却不如我们所愿,总是有残留的布局在占着位子,挥之不去,无论你怎么clear、remove都于是无补,因为我不懂它的实现机制,so,真心被动。折腾了好几天,终于在stackoverflow上找到了问题的根源,结合自己项目实际情况解决了自己的问题,详情见下文。
所以说:软件开发有两种东西是不可或缺的--1.勇于尝试;2.良好的英文阅读能力!!
项目使用情况:viewpager+FragmentPagerAdapter+fragment,交互逻辑放置在fragment中;
1.主activity中的动态动态增删逻辑,因为涉及到动态 刷新,所以在每次动态添加之前要先将其清空一下

layout.removeAllViews();//涉及到实时刷新,所以要将之前的布局清空掉。
        homePager.removeAllViewsInLayout();//removeAllViews();//赋值之前先将Adapter中的
        homepageFragments.clear();
        if(hotIssuesList != null && hotIssuesList.size()>0) {
            describeArr = new String[hotIssuesList.size()];
            solutionArr = new String[hotIssuesList.size()];
            for(int i = 0; i < hotIssuesList.size(); i++) {//hotIssuesList.size()
                describeArr[i] = hotIssuesList.get(i).getHotDescirbe();//提取对应pager数据源。
                solutionArr[i] = hotIssuesList.get(i).getHotSolution();
                img = new ImageView(this);//准备5个小图标。
                img.setScaleType(ScaleType.FIT_XY);
                img.setImageResource(img_ID);
                imgsList.add(img);
                img.setPadding(6, 3, 6, 3);
                layout.addView(img, params);
                
//                colourFragment = new ColourFragment(hotIssuesList.get(i));
//                homepageFragments.add(colourFragment);
//                homePage2Fragment = new HomePage2Fragment(this, i, hotIssuesList.get(i));
                homePage2Fragment = HomePage2Fragment.getInstance(hotIssuesList.get(i));
//                homePage2Fragment = new HomePage2Fragment(this, i, new String[]{describeArr[i], solutionArr[i]});
                homepageFragments.add(homePage2Fragment);
//                viewpagerItemView = new ViewPagerItemView(this, i, new String[]{describeArr[i], solutionArr[i]});
//                homepageViews.add(viewpagerItemView);
            }
            
            //custom-viewpager
//            MyHomePagerAdapter myAdapter = new MyHomePagerAdapter(this, homepageViews, describeArr, solutionArr);
            HomePageAdapter adapter = new HomePageAdapter(this, getSupportFragmentManager(), homepageFragments);
            homePager.setAdapter(adapter);
            
            //wrapper-viewpager-
//            HomePageAdapter adapter = new HomePageAdapter(this, getSupportFragmentManager(), hotIssuesList);
//            PagerAdapter wrappedAdapter = new InfinitePagerAdapter(adapter);
//            homePager.setAdapter(wrappedAdapter);
            
            homePager.setCurrentItem(0);
            imgsList.get(0).setImageResource(img_ID_ov);
            homePager.setOnPageChangeListener(new PageListener());
        }

代码中可以看出我已经做过了各种尝试,哎,解决一个问题真的比首次开发难度大多了。
2.最关键的地方出来了:--pagerAdapter, 一定要替换成下文的样式才能正常删除fragment

public class HomePageAdapter extends FragmentStatePagerAdapter {//FragmentPagerAdapter

//    private FragmentManager fm;
    private ArrayList<Fragment> fragments = null;
    private List<HotIssues> hotIssuesList;
    private Context context;

    public HomePageAdapter(Context context, FragmentManager fm, ArrayList<Fragment> fragments) {
        super(fm);
        this.context = context;
        this.fragments = fragments;
        notifyDataSetChanged();
    }
    
    public HomePageAdapter(Context context, FragmentManager fm, List<HotIssues> hotIssuesList) {
        super(fm);
        this.context = context;
        this.hotIssuesList = hotIssuesList;
        notifyDataSetChanged();
//        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int arg0) {
//        Fragment fragment = new ColourFragment();
//        Bundle args = new Bundle();
//        args.putInt("title", arg0);
//        args.putSerializable("content",hotIssuesList.get(arg0));
//        fragment.setArguments(args);
//        return fragment;
        return fragments.get(arg0);
    }

    @Override
    public int getItemPosition(Object object) {
        // TODO Auto-generated method stub
        return PagerAdapter.POSITION_NONE;
    }
    
    @Override
    public int getCount() {
        return fragments.size();//hotIssuesList.size();
    }
    
}

注:引用stackoverflow牛人的解决说明:

The ViewPager doesn't remove your fragments with the code above because it loads several views (or fragments in your case) into memory. In addition to the visible view, it also loads the view to either side of the visible one. This provides the smooth scrolling
from view to view that makes the ViewPager so cool.

To achieve the effect you want, you need to do a couple of things.

  1. Change the FragmentPagerAdapter to a FragmentStatePagerAdapter. The reason for this is that the FragmentPagerAdapter will keep all the views that it loads into memory forever. Where the FragmentStatePagerAdapter disposes of views that fall outside the current
    and traversable views.

  2. Override the adapter method getItemPosition (shown below). When we callmAdapter.notifyDataSetChanged(); the
    ViewPager interrogates the adapter to determine what has changed in terms of positioning. We use this method to say that everything has changed so reprocess all your view positioning。

大致意思是说:viewpager在加载当前页的时候已经将pager页左右页的内容加载进内存里了,这样才保证了viewpager左右滑动的时候的流畅性;
为了解决彻底删除fragment,我们要做的是:
1.将FragmentPagerAdapter 替换成FragmentStatePagerAdapter,因为前者只要加载过,fragment中的视图就一直在内存中,在这个过程中无论你怎么刷新,清除都是无用的,直至程序退出; 后者 可以满足我们的需求。

  @Override
    public int getItemPosition(Object object) {
        // TODO Auto-generated method stub
        return PagerAdapter.POSITION_NONE;
    }

最后重申一句:一定要训练阅读外文文献、网页的能力!
http://stackoverflow.com/questions/10396321/remove-fragment-page-from-viewpager-in-android

2.我们可以重写Adapter的方法--getItemPosition(),让其返回PagerAdapter.POSITION_NONE即可;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值