您的位置:首页 > 移动开发 > Android开发

Fragment初解

2016-03-02 15:05 471 查看

Fragment初解

Fragment是什么

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

拥有自己的界面

拥有自己的生命周期

接收自己的输入事件

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

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

Fragment生命周期

在聊Fragment生命周期之前,我们先看一副Android官网的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生命周期的关系。



我们可以很清晰的看见除了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的状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android