Fragment

Fragment是Android 3.0 被引入的,在主流app中非常常见,它有着自己的生命周期,同时也依赖与Activity。

Fragment 的使用

在xml中使用FrameLayout来作为Fragment的容器布局

 <FrameLayout
    android:id="@+id/frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
 private List<Fragment> fragmentList;
 private int lastIndex = 0;

 private void initFragment() {
        fragmentList = new ArrayList<>();
        fragmentList.add(new Test1Fragment());
        fragmentList.add(new Test2Fragment());
        fragmentList.add(new Test3Fragment());
        selectFragment(1);
    }

    private void selectFragment(int index) {
		//获取fragment事务管理器
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
		//将要展示的fragmrnt
        Fragment currentFragment = fragmentList.get(index);
		//在展示的fragment
        Fragment lastFragment = fragmentList.get(lastIndex);
        lastIndex = index;
		//隐藏以展示的
        transaction.hide(lastFragment);
        if (!currentFragment.isAdded()) {
            getSupportFragmentManager().beginTransaction().remove(currentFragment).commit();
            transaction.add(R.id.frame_layout, currentFragment);
        }
        transaction.show(currentFragment);
        transaction.commitAllowingStateLoss();
    }

ViewPage

ViewPage左右切换当前的view,实现滑动切换的效果。 ViewPager类需要PagerAdapter适配器类提供数据,而ViewPage有三个适配器类:

PagerAdapter

public class MyViewPagerAdapter extends PagerAdapter{
     private List<View> mListViews;

     public MyViewPagerAdapter(List<View> mListViews) {
        this.mListViews = mListViews;//构造方法,参数是我们的页卡,这样比较方便。
     }
    //直接继承PagerAdapter,至少必须重写下面的四个方法,否则会报错
     @Override
     public void destroyItem(ViewGroup container, int position, Object object)  {   
        container.removeView(mListViews.get(position));//删除页卡
      }

     @Override
     public Object instantiateItem(ViewGroup container, int position){
        //这个方法用来实例化页卡       
        container.addView(mListViews.get(position), 0);//添加页卡
        return mListViews.get(position);
     }
     @Override
     public int getCount() {            
        return  mListViews.size();//返回页卡的数量
     }
        
     @Override
     public boolean isViewFromObject(View arg0, Object arg1) {          
        return arg0==arg1;//官方提示这样写
     }
 }

FragmentPagerAdapter

public class FragmentViewPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> mFragment;

    public FragmentViewPagerAdapter(FragmentManager fm, List<Fragment> mFragments) {
        super(fm);
        this.mFragment = mFragments;
    }

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

    @Override
    public int getCount() {
        return mFragment.size();
    }
}

注意:FragmentStatePagerAdapter与FragmentPagerAdapter使用方式一致,FragmentStatePagerAdapter 适合大量页面,不断重建和销毁 FragmentPagerAdapter 适合少量页面,常驻内存。

使用方式

FragmentViewPagerAdapter pagerAdapter = new FragmentViewPagerAdapter(getSupportFragmentManager(), mFragments);
viewPage.setOffscreenPageLimit(1);
viewPage.setAdapter(pagerAdapter);
viewPage.setCurrentItem(position);

Fragment的容器的管理者

这里无论是Fragment还是viewpage的fragment是用的容器的管理者都是getSupportFragmentManager(),但是当我们在fragment中使用viewpage或者fragment的时候就会发现问题,后面嵌套的fragment不会执行对应的生命周期,那这是为什么呢?这个就和fragment的容器的管理者有关了

getChildFragmentManager和getsupportFragmentManager和getFragmentManager的关系

getFragmentManager到的是activitry对所包含fragment的Manager,而如果是fragment嵌套fragment,那么就要利用getChildFragmentManager()了。参考