一:概念 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的容器。
新闻热点
疑难解答