写点什么

Android 进阶 (十二)Fragment 与 Activity 讲解

  • 2022 年 8 月 13 日
    江苏
  • 本文字数:2812 字

    阅读完需:约 9 分钟

Android进阶(十二)Fragment与Activity讲解

一、前言

Android 是在 Android 3.0 (API level 11)开始引入Fragment的。可以把 Fragment 想成 Activity 中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,在Activity运行的时候可以加载或者移除Fragment模块。可以把Fragment设计成可以在多个Activity中复用的模块。

  当开发的应用程序同时适用于平板电脑和手机时,可以利用 Fragment 实现灵活的布局,改善用户体验。

  如图:


二、Fragment 的生命周期

  因为Fragment必须嵌入在Acitivity中使用,所以Fragment的生命周期和它所在的Activity是密切相关的。

  如果Activity是暂停状态,其中所有的Fragment都是暂停状态;如果Activity是 stopped 状态,这个Activity中所有的Fragment都不能被启动;如果Activity被销毁,那么它其中的所有Fragment都会被销毁。

  但是,当 Activity 在活动状态,可以独立控制 Fragment 的状态,比如加上或者移除 Fragment。

  当这样进行fragment transaction(转换)的时候,可以把fragment放入Activityback stack中,这样用户就可以进行返回操作。



三、Fragment 使用相关

  使用 Fragment 时,需要继承 Fragment 或者 Fragment 的子类(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以 Fragment 的代码看起来和 Activity 的类似。


使用 Support Library

  Support Library是一个提供了 API 库函数的 JAR 文件,这样就可以在旧版本的 Android 上使用一些新版本的 APIs。

  比如 android-support-v4.jar.它就提供了 Fragment 的 APIs,使得在 Android 1.6 (API level 4)以上的系统都可以使用 Fragment。

  为了确定没有在旧版本系统上使用新版本的 APIs,需要如下导入语句:

  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentManager;
复制代码

  同时应该将上述的包拷入 libs 项目下的 libs 文件夹,然后在项目的 Properties 中添加:右键单击项目,选 Properties,左边选 Java Build Path,然后 Add External JARs…,添加 android-support-v4.jar.



  当创建包含 Fragment 的 Activity 时,如果用的是 Support Library,那么继承的就应该是 FragmentActivity 而不是 Activity。

  onCreate()

  系统在创建 Fragment 的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。

  onCreateView()

  当第一次绘制 Fragment 的 UI 时系统调用这个方法,必须返回一个 View,如果 Fragment 不提供 UI 也可以返回 null。

  注意,如果继承自 ListFragment,onCreateView()默认的实现会返回一个 ListView,所以不用自己实现。

onPause()

  当用户离开 Fragment 时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。

四、实现 Fragment 的 UI

  提供 Fragment 的 UI,必须实现 onCreateView()方法。

  假设 Fragment 的布局设置写在 example_fragment.xml 资源文件中,那么 onCreateView()方法可以如下写:

public static class ExampleFragment extends Fragment{    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState)    {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.example_fragment, container, false);    }
复制代码

  onCreateView()中 container 参数代表该 Fragment 在 Activity 中的父控件;savedInstanceState 提供了上一个实例的数据。

  inflate()方法的三个参数:

  第一个是 resource ID,指明了当前的 Fragment 对应的资源文件;

  第二个参数是父容器控件;

  第三个布尔值参数表明是否连接该布局和其父容器控件,在这里的情况设置为 false,因为系统已经插入了这个布局到父控件,设置为 true 将会产生多余的一个 View Group。

五、把 Fragment 加入 Activity

  当 Fragment 被加入 Activity 中时,它会处在对应的 View Group 中。

  Fragment 有两种加载方式:一种是在 Activity 的 layout 中使用标签<fragment>声明;另一种方法是在代码中把它加入到一个指定的 ViewGroup 中。

  另外,Fragment 它可以并不是 Activity 布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。

5.1 加载方式 1:通过 Activity 的布局文件将 Fragment 加入 Activity

  在 Activity 的布局文件中,将 Fragment 作为一个子标签加入即可。如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>
复制代码

  其中 android:name 属性填上你自己创建的 fragment 的完整类名。

  当系统创建这个 Activity 的布局文件时,系统会实例化每一个 fragment,并且调用它们的 onCreateView()方法,来获得相应 fragment 的布局,并将返回值插入 fragment 标签所在的地方。

  有三种方法为 Fragment 提供 ID:

  android:id 属性:唯一的 id

  android:tag 属性:唯一的字符串

  如果上面两个都没提供,系统使用容器 view 的 ID。

5.2 加载方式 2:通过编程的方式将 Fragment 加入到一个 ViewGroup 中

  当 Activity 处于Running状态下的时候,可以在 Activity 的布局中动态地加入 Fragment,只需要指定加入这个Fragment的父 View Group 即可。

  首先,需要一个 FragmentTransaction 实例: 

FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
复制代码

 (注:如果 import android.support.v4.app.FragmentManager;那么使用的是:FragmentManager fragmentManager = getSupportFragmentManager();)

  之后,用 add()方法加上 Fragment 的对象:

ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
复制代码

  其中第一个参数是这个 fragment 的容器,即父控件组。

  最后需要调用 commit()方法使得 FragmentTransaction 实例的改变生效。

发布于: 刚刚阅读数: 4
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Android进阶(十二)Fragment与Activity讲解_android_No Silver Bullet_InfoQ写作社区