替换ViewPager中某一页的Fragment

来源:互联网 发布:事业单位面试网络课程 编辑:程序博客网 时间:2024/06/07 01:45

    转载注明出处!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!http://blog.csdn.net/mieleizhi0522/article/details/78697846

    第一次写这么正经的写一个帖子,还是查了很多资料之后写的,终于找到了解决方案,虽然别人给的不全,而我却摸索着实现了功能,给自己一个大大的赞,接下来我也要分享给大家!

     本实现主要解决了一个问题,我有一个ViewPager,里面存放了4个Pager,当然这些Pager都是通过Fragment来实现的,适配器用的是FragmentStatePagerAdapter,我现在主要实现的功能是第二个Fragment2,上面有一个OK按钮,点击OK的时候第二个Fragment2会被替换成另一个Fragment2_2,其余Fragment1,Fragment3,Fragment4不变,依然在原来的位置,当然替换之后你仍然可以随意滑动,只是Fragment2不是之前的Fragment2了

接下来我简单说一个我的想法吧,

1,网上的普遍做法

    大概意思是通过修改原来存储Fragment的List<Fragment>来实现新的页面显示,之前List<Fragment>里面装的是1,2,3,4,如果点击2上面的OK按钮后,删掉所有List<Fragment>中的元素,重新填充,填成1,2-2,3,4,然后显示,这样就实现了修改Fragment2的方法,你感觉这样好吗,反正我感觉这样不好,具体实现我就不说了,大家可以查一下。

2.,我找到的办法

     首先大概补充一个FragmentStatePagerAdapter和FragmentPagerAdapter的不同,这个你应该有所了解,不过不了解也没关系,我的做法这两个都适用 

       (1).使用FragmentStatePagerAdapter会销毁掉不需要的fragment。事务提交后,可将fragment从activity的FragmentManager中彻底移除。类名中的“state”表明:在销毁fragment时,它会将其onSaveInstanceState(Bundle) 方法中的Bundle信息保存下来。用户切换回原来的页面后,保存的实例状态可用于恢复生成新的fragment.
      (2).FragmentPagerAdapter的做法大不相同。对于不再需要的fragment,FragmentPagerAdapter则选择调用事务的detach(Fragment) 方法,而非remove(Fragment)方法来处理它。也就是说,FragmentPagerAdapter只是销毁了fragment的视图,但仍将fragment实例保留在FragmentManager中。因此, FragmentPagerAdapter创建的fragment永远不会被销毁。

      接下来转入正题,我所做的主要思路是public Fragment getItem(int position)通过位置加载要显示的页面(也就是在适配器中的位置),我们知道这个之后不就可以替换了吗,这个替换不是replace,而是remove旧的,然后new一个新的给页面,这个新的就是Fragment2_2,为什么不能用replace,因为replace里面有两个参数,第一个是容器的id,容器的id我们不好找的,有人说是ViewPager这个容器的id,那么你想想如果用这个容器会发生什么情况,当然不是啊,因为这个容器里面存了4个页面,你如果替换的话是替换掉哪一个,不知道吧!所以这个ViewPager容器和Fragment容器还是不一样的,接下来直接上代码了,如果不懂可以留言,我基本上都在。

public class MyFragmentViewPagerAdapter extends FragmentStatePagerAdapter {    private List<Fragment> datas;//适配器里面要传入一些参数,在ViewPage里面传入的是View参数,    // 也就是普通布局参数,但是在这个里面要传入Fragment参数    private List<String> titles;    private  FragmentManager mfragmentManager;    private Fragment mfragmentAtPos1;    public MyFragmentViewPagerAdapter(FragmentManager fm,List<Fragment> datas,List<String> titles) {        super(fm);//重写父类有参构造方法        this.mfragmentManager=fm;        this.datas=datas;        this.titles=titles;    }    @Override    public Fragment getItem(int position) {        if(position==1){//第二个页面替换            if(mfragmentAtPos1==null){//如果加载的时候这个是空(其实刚启动ViewPager的时候这个值都是空的)                mfragmentAtPos1=fragment2.newIntance(new FirstPageFragmentListener(){//如果上面的值是空,就new一个旧的fragment2                    @Override                    public void onSwitchToNextFragment() {//fragment2中带有的替换监听事件                     mfragmentManager.beginTransaction().remove(mfragmentAtPos1).commit();//监听触发后移除掉旧的(刚才new的fragment2)                         mfragmentAtPos1= fragment2_2.newIntance();//替换成新的                        notifyDataSetChanged();//这个必须要有,可以查看这个方法的意思,就明白了                    }                });            }            return mfragmentAtPos1;        }        else        return datas.get(position);    }   public interface FirstPageFragmentListener{        void onSwitchToNextFragment();   }    @Override    public int getCount() {        return datas.size();    }    @Override    public CharSequence getPageTitle(int position) {       return titles.get(position);       //return null;    }    /**     * 初始化子页面     * @param container     * @param position     * @return     */    @Override    public Object instantiateItem(ViewGroup container, int position) {        return super.instantiateItem(container, position);    }    /**     * 销毁不可见的页面     * @param container     * @param position     * @param object     */    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        super.destroyItem(container, position, object);    }    @Override    public int getItemPosition(Object object) {        if(object instanceof fragment2 && mfragmentAtPos1 instanceof fragment2_2)            return POSITION_NONE;        return POSITION_UNCHANGED;    }}
最后在fragment2里面实现按钮监听就可以了

如果需要源代码在这里http://download.csdn.net/download/mieleizhi0522/10142225