Fragment 是 Android3.0(API 11) 推出来的新的UI控件。一个Activity里可以有多个Fragment,反过来,一个Fragment可以被多个Activity重用。因此相比使用Activity, 使用 Fragment 能更好的做到view的解耦。Fragment 是一个比较复杂的控件,因此我们将分几篇文章来介绍。
在第一篇中我们先构建一个简单的 Fragment, 让大家对 Fragment 有一个初步的印象,知道它能做什么?
建立 Fragment 布局文件 类似于 Activity, 一个 Framgent 通常由一个类文件和一个布局文件构成。 在这里,我们先构建一个布局文件
在菜单中选择 File -> New -> XML -> Layout XML File,根据提示输入文件名: fragment_todo.xml。 然后 Android Studio 会建立并打开 fragment_todo.xml 文件并进入 Design 模式。从工具箱(Palette)中拖入一个 TextView 和一个 Button。 设定 TextView 的 id 为: tvwHello, Button 的 id 为:btnOk。 然后简单的设置以下布局参数,让两个控件上下排列即可。完成后的 xml 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="match_parent" android:layout_height ="match_parent" android:orientation ="vertical" > <TextView android:id ="@+id/tvwHello" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_weight ="1" android:text ="This is Todo Fragment" /> <Button android:id ="@+id/btnOk" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_weight ="1" android:text ="@android:string/ok" /> </LinearLayout >
建立 Fragment 类 在项目中新建一个类,命名为: TodoFragment,设定其父类为 Fragment。 完成后的代码如下:
1 2 3 public class TodoFragment extends Fragment {}
接下来,我们使用 butterknife 来绑定屏幕中的控件。(如果不熟悉 butterknife 的用法,可以参考 在Android中使用注解绑定控件和事件 )
绑定以后的代码为:
1 2 3 4 5 6 7 8 9 public class TodoFragment extends Fragment { @BindView (R.id.tvwHello) TextView tvwHello; @OnClick (R.id.btnOk) void onOk () { tvwHello.setText("Hello" ); } }
最后,加入 Fragment 的初始化代码, 每个 Fragment 由自己的生命周期,我们需要在生命周期中的初始化中完成对布局和类的绑定,就像使用 Activity 时,需要在 onCreate 方法中用 setContentView 完成对布局和类的绑定一样。但在 Fragment 中,需要使用 onCreateView 方法。 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_todo, container, false ); ButterKnife.bind(this , view); return view; } `` 全部完成后的完整 Fragment 代码如下: ``` java public class TodoFragment extends Fragment { @BindView (R.id.tvwHello) TextView tvwHello; public void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); } @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_todo, container, false ); ButterKnife.bind(this , view); return view; } @OnClick (R.id.btnOk) void onOk () { tvwHello.setText("Hello" ); } }
使用 Fragment 在程序中,Fragment 不能单独显示,需要将其放到 Activity 中。 由两种方法可以将 Fragment 放入 Activity 中,一种是静态方法,一种是动态方法,本文介绍静态方法。选择你要放置 Fragment 的 Activity 所对应的布局文件,比如 activity_main.xml。在 Design 试图中,在工具箱(Palette)中选择 fragment, 拖入界面,系统会提示你选择 Fragment, 选择刚才建立的 TodoFragment。完成后的布局代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".MainActivity" > <fragment android:id ="@+id/fragment1" android:name ="cn.com.hohistar.tutorial.fragmenttutorial.TodoFragment" android:layout_width ="361dp" android:layout_height ="176dp" android:layout_marginStart ="27dp" android:layout_marginLeft ="27dp" android:layout_marginTop ="73dp" android:layout_marginEnd ="27dp" android:layout_marginRight ="27dp" android:layout_weight ="1" app:layout_constraintEnd_toEndOf ="parent" app:layout_constraintStart_toStartOf ="parent" app:layout_constraintTop_toTopOf ="parent" /> </androidx.constraintlayout.widget.ConstraintLayout >
然后就可以运行程序,查看效果。
通过这个简单的程序可以看到,Fragment 把原来在 Activity 中的功能模块化了,UI 及相应的代码被打包在了 Fragment 中,这样既有利于减轻 Activity 的复杂度,提高代码的可读性,也有利于代码的复用。