Fragment初解

Fragment是什么####

Fragment是用来呈现Activity部分界面的一种特殊组件。从Android 3.0系统开始对平板设备进行适配,而Fragment是为其而生的组件。引入Fragment可以让开发者可以更有效的利用平板设备大屏幕的优势,从而为用户创建更佳的用户体验,演变到现在已经是常用代替Activity展现界面的组件。Fragment具有以下特性:

  • 拥有自己的界面

  • 拥有自己的生命周期

  • 接收自己的输入事件

  • Activity是其唯一的载体,即依赖于Activity.

    因为Fragment必须依赖Activity而生存,所以Fragment的生命周期与Activity的生命周期息息相关。例如当Activity处于暂停状态时候,Fragment亦处于暂停状态,且该生命周期中的onPause回调函数会被调用。


Fragment生命周期####

在聊Fragment生命周期之前,我们先看一副Android官网的Fragment生命周期图:
Fragment生命周期
我们可以看到除了onAttach()、onCreateView()、onActivityCreated()、onDestoryView()、onDetach()之外,其他的生命周期回调函数均与Activity无异。下面是相应生命周期方法的描述:
- onAttach():Fragment被添加到Activity的时候会被调用
- onCreate():Fragment首次创建时候,这里我们一般会做一些成员变量的初始化。
- onCreateView():当Fragment视图需要被创建时候,这个是Fragment创建界面的唯一入口,我们通过该回调方法创建该Fragment显示的内容,Activity亦是通过该方法获取Fragment创建的视图引用。
- onActivityCreated():如果Fragment所在的Activity的onCreate()已经被回调完毕时候,那么每次添加Fragment的时候会调用该回调,以此判别该Activity是否已经被创建。
- onStart()、onResume():与Activity onStart()、onResume()被调用的时机是一样的。
- onPause()、onStop():与Activity onPause()、onStop()被调用的时机是一样的。
- onDestoryView():Fragment视图被销毁的时候。这里我们就应该释放一些界面上的资源
- onDestory():Fragment被销毁的时候
- onDetach():Fragment从Activity中被移除
接下来我们看看Fragment与Activity生命周期的关系。

Fragment与Activity生命周期
我们可以很清晰的看见除了Created状态与Destoryed状态外,Fragment的生命周期与Activity基本是同步的。只不过Fragment在这两个状态中,附加了自己独有的生命周期回调。


什么情况下建议使用Fragment####

  • 平板设备情况设计界面时候,建议使用Fragment,可以更有效的发挥平板屏幕优势。
  • 当界面需要整体变化时候,建议使用Fragment代替使用Activity,因为Fragment比Activity更加轻量,而且Fragment更注重于界面设计。例如惯用的主页框架,底部有几个Tab,这种情况下我们可以让每个Tab的内容都是Fragment。

使用Fragment####

我们简单的描述一下Fragment的使用。

1.继承Fragment
2.重写onCreateView方法来创建我们需要显示的视图内容
3.对Fragment进行操作,将其添加到Activity中,或者从Activity中移除
添加Fragment的方式有两种:

  • 通过XML布局文件
  • 通过硬编码动态添加

我们看看下面的样例:

//创建 ExampleFragmnet.class
public class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
         //这里创建Fragment内容视图
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}
<!--XML布局文件方式添加Fragment,该布局文件为Activity的布局文件-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--这里通过声明一个fragment标签在Activity布局里面来添加Fragment-->
    <fragment android:name="com.example.ExampleFragment "
            android:id="@+id/fragment_1"
            android:tag ="example"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</LinearLayout>
//硬编码形式添加Fragment
private void addFragment(){
	//获取Fragment管理类,我们需要继承FragmentActivity才可以对Fragment进行管理
	FragmentManager fragmentManager = getFragmentManager();
	//开始一个Fragment的操作过程
	FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
	//创建Fragment实例
	ExampleFragment fragment = new ExampleFragment();
		//将Fragment添加到R.id.fragment_container视图容器中
		//该视图容器在Activity布局文件中声明,Fragment视图内容将在该视图容器中显示
	fragmentTransaction.add(R.id.fragment_container, fragment);
	//最后提交这次的Fragment操作.
	fragmentTransaction.commit();
}

Fragment嵌套子Fragment####

Fragment支持嵌套子Fragment.使用方式与上面Activity里面使用Fragment一致,只是在获取FragmentManager时候需要通过Fragment对象获取而不是通过FragmentActivity,获取方式如下:

Fragment.getChildFragmentManager()

Fragment与ViewPager####

Fragment的初衷是为了发挥平板设备的屏幕优势,演变到现在已经是构成主界面框架常见的组件了。而最常用的莫过于与ViewPager配合构建成可滑动的Tab类型的主界面。之所以会与ViewPager配合,这里猜测主要是因为两点:

  • ViewPager提供了左右滑动动画效果
  • ViewPager自动管理Fragment的生命周期.

我们这里重点分析ViewPager如何管理Fragment的生命周期,并且其中一些需要注意的地方。
首先,ViewPager怎么管理Fragment?

ViewPager实质上是通过适配器管理Fragment.适配器有两种,FragmentPagerAdapter与FragmentStatePagerAdapter。

如果对ViewPager了解不深的话,可以看看前面的《ViewPager与PagerAdapter深度分析》。这里我们具体通过FragmentPagerAdapter与FragmentStatePagerAdapter的源码来看看他们如何管理Fragment。
FragmentPagerAdapter主要重写了下面几个方法管理Fragment。我们一一从源码分析。

public abstract class FragmentPagerAdapter extends PagerAdapter {
	...
    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;
    public FragmentPagerAdapter(FragmentManager fm) {
        mFragmentManager = fm;
    }
	...
	//在《ViewPager与PagerAdapter深度分析》我们有解释过instantiateItem在ViewPager创建新项的时候被调用
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
		//创建操作Fragment的事务
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        final long itemId = getItemId(position);
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        //Fragment已经创建,直接attach该Fragment
        if (fragment != null) {
            mCurTransaction.attach(fragment);
        } else {
	        //这里我们需要重写getItem方法提供Fragment
            fragment = getItem(position);
	        //将Fragment添加到FragmentManager里面去
	        //这里也会将Fragment的View添加到ViewPager容器当中去
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
	    ...
        return fragment;
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
	    //创建移除Fragment的事务
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        mCurTransaction.detach((Fragment)object);
    }
    ...
    @Override
    public void finishUpdate(ViewGroup container) {
	    //这里提交Fragment事务
        if (mCurTransaction != null) {
            mCurTransaction.commitAllowingStateLoss();
            mCurTransaction = null;
            mFragmentManager.executePendingTransactions();
        }
    }
   ...
}

当ViewPager创建页面的时候,会去调用FragmentPagerAdapter.instantiateItem(ViewGroup,int)创建一个Fragment事务,如果该页面的Fragment还未被创建,则通过调用FragmentPagerAdapter.getItem(int)创建Fragment并通过FragmentTransaction .add(..) 添加到Fragment中,在添加的过程中,会将Fragment相应的View添加到ViewPager中。
当ViewPager需要销毁某个页面的时候,会调用FragmentPagerAdapter. destroyItem(ViewGroup, int, Object) 移除Fragment。
当ViewPager页面完成更新的时候,会提交Fragment事务,注意的是,这里可能会丢失Fragment的状态。

posted @ 2017-12-15 11:11  Zhouztashin  阅读(136)  评论(0编辑  收藏  举报