一:概念
Fragment表现Activity中用户界面的一个行为或者是一部分。你可以在一个单独的activity上把多个fragment组合成为一个多区域的UI,并且可以在多个activity中再使用。你可以认为fragment是activity的一个模块零件,它有自己的生命周期,接收它自己的输入事件,并且可以在activity运行时添加或者删除。
Fragment必须总是被嵌入到一个activity之中,并且fragment的生命周期直接受其宿主activity的生命周期的影响。例如,一旦activity被暂停,它里面的所有的fragment也被暂停,一旦activity被销毁,它里面所有的fragment也被销毁。fragment本身不具有在屏幕上显示视图的能力,只有将它的视图放置在activity的视图结构中,fragment视图才能显示在屏幕上。
二:fragment与支持库
我们要用到两个重要的支持库类,一个是Fragment类 (android.support.v4.app.Fragment),另一个是FragmentActivity(android.support.v4.app.Fragment- Activity)。
使用fragment的前提是,activity知道如何管理fragment。FragmentActivity类知道如何管理支持
版本的fragment。
fragment是3.0以后的东西,为了在低版本中使用fragment就要用到android-support-v4.jar兼容包,而fragmentActivity就是这个兼容包里面的,它提供了操作fragment的一些方法,其功能跟3.0及以后的版本的Activity的功能一样。
在 Android Studio 中增加依赖关系
选择File → ProjectStructure…菜单项打开项目结构对话框。
选择左边的应用模板,然后在右边点击Dependencies选项页。可以看到,应用模板的依赖项
都列在这了,如图7-10所示
单击+号按钮,在选择Library dependency界面添加新的依赖项,如图7-11所示。从列表中选
中support-v4库后单击OK按钮确认。
com.android.support包中有很多不
同的库,如support-v13、appcompat-v7和gridlayout-v7。Google使用basename-vX模式作为支持库
的命名约定。-vX指所支持的最低API级别。因此,以appcompat-v7为例,这里的-v7就是说Google
兼容库可以应用到Android API 7及以上级别的设备上。
三。托管Fragment
1生命周期
activity托管UI fragment有如下两种方式:
在activity布局中添加fragment;
在activity代码中添加fragment。
第一种方式就是使用布局fragment。这种方式简单但不够灵活。在activity布局中添加
fragment,就等同于将fragment及其视图与activity的视图绑定在一起,并且在activity的生命周期
过程中,无法切换fragment视图。
第二种方式比较复杂,但也是唯一可以在运行时控制fragment的方式。我们自行决定何时添
加fragment以及随后可以完成何种具体任务;也可以移除fragment,用其他fragment代替当前
fragment,然后重新添加已移除的fragment。
2.一步步构建
1)定义容器视图用来安排fragment
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/
2)定义Fragment布局
这里只添加了一个Edit Text
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="fragment"/>
</LinearLayout>
3)创建Fragment类
fragment的视图并没 有在Fragment.onCreate(…)方法中生成。创建和配置fragment视图是另一个
fragment生命周期方法完成的:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
该方法实例化 fragment 视图的布局,然后将实例化的 View 返回给托管 activity 。
LayoutInflater及ViewGroup是实例化布局的必要参数。Bundle用来存储恢复数据,可供该方
法从保存状态下重建视图。
public class EnvironmentFragment extends Fragment {
Envrionment mEnvrionment;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_environment,container,false);
return v;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mEnvrionment = new Envrionment();
}
}
onCreateView(…) 方法中, fragment 的视图是直接通过调用 LayoutInflater.
inflate(…)方法并传入布局的资源ID生成的。第二个参数是视图的父视图,我们通常需要父
视图来正确配置组件。第三个参数告知布局生成器是否将生成的视图添加给父视图。这里,我们
传入了false参数,因为我们将以activity代码的方式添加视图。
4)添加fragment到FragmentManager
FragmentManager类负责管理fragment并将它们的视图添加到activity的视图层级结
构中。首先,我们需要获取FragmentManager本身
在托管activity中添加如下代码
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enviroment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if(fragment == null){
fragment = new EnvironmentFragment();
fm.beginTransaction().add(R.id.fragment_container,fragment).commit();
}
}
fragment事务被用来添加、移除、附加、分离或替换fragment队列中的fragment。这是使用
fragment在运行时组装和重新组装用户界面的关键。FragmentManager管理着fragment事务回
退栈。
FragmentManager.beginTransaction()方法创建并返回FragmentTransaction实例。
FragmentTransaction类使用了名为fluent interface的接口方法,通过该方法配置FragmentTransaction返回FragmentTransaction类对象,而不是void,由此可得到一个FragmentTransaction队列。
add(…)方法是整个事务的核心,它含有两个参数:容器视图资源ID和新创建的
CrimeFragment。容器视图资源ID我们应该很熟悉了,它是定义在activity_crime.xml中的
FrameLayout组件的资源ID。
容器视图资源ID的作用有:
告诉FragmentManager,fragment视图应该出现在activity视图的什么位置;
用作FragmentManager队列中fragment的唯一标识符。
如需从FragmentManager中获取CrimeFragment,使用容器视图资源ID就行了:
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
FragmentManager使用FrameLayout组件的资源ID去识别CrimeFragment,这看上去可能有点
怪。但实际上,使用容器视图资源ID去识别UI fragment是FragmentManager的内部实现机制。如
果要向activity添加多个fragment,通常需要分别为每个fragment创建不同ID的容器。