Android app开发中的Fragment入门学习教程

时间:2021-10-15 22:29:59

在android3.0上开始引入了一个新概念叫fragment。它有自己的布局文件,可以作为组件排布,也可以相互组合去实现不同的布局显示。使用fragment可以重复利用代码,并且可以满足不同设备尺寸的需求。fragment不能单独存在,只能存在于activity中,而一个activity可以拥有多个fragment。很重要的一点是,fragment可以和activity中的其它组件一起使用,无需重写所有activity的接口。所以使用fragment就可以这样来完成上例中“主界面—详细界面”的app需求。

在手机上是这样显示的:

Android app开发中的Fragment入门学习教程

而在平板上是这样的:

Android app开发中的Fragment入门学习教程

在一个小屏幕的设备上,一个activity通常占据了整个屏幕,同时显示各种ui视图组件。activity实际上就是视图的容器。然后,当一个activity被显示在一个大屏幕的设备上,例如平板电脑,总会显得有些不适应。因为屏幕太大了,activity中的所有ui组件要充满整个屏幕,这样一来,视图的层次结构就很复杂了。一个更好的办法是使用一种“轻量级”的activity,每个“轻量级”activity包含自己的视图,互不干扰。在运行期间,根据屏幕的方向和尺寸,一个activity可以包含一个或多个“轻量级”activity。在android3.0以上的版本,这种“轻量级”的activity叫做fragment.

怎么创建一个fragment

现在我们了解了fragment的生命周期了,接着我们就需要知道怎么创建一个fragment并绑定到activity中,第一件要做的事就是继承android.app.fragment来写一个fragment,假设我们的fragment叫做fragment1,创建和定义如下:

?
1
2
3
public class fragment1 extends fragment {
...
}

就像我们上面说的,fragment只能存在于activity中,所以我们必须要在某处定义它,有两种方式:
- 直接在xml布局文件中定义;
- 在xml布局文件中定义一个占位符,然后动态地在activity中操作fragment;

我们定义fragment的方式会影响它的生命周期,因为在上述第一种情况下oninflate方法会被调用,而第二种情况下它的生命周期是从onattach方法开始的。

如果我们在xml文件中定义fragment的话,我们需要:

?
1
2
3
4
<fragment android:id="@+id/f1"
            class="com.survivingwithandroid.fragment.fragment1"
       android:layout_width="match_parent"
       android:layout_height="20dp"/>

然而如果我们在xml中用占位符的话,需要再做一些工作。

布局框架和fragment

如果我们在xml布局文件中定义fragment的话,就不能*、动态修改fragment了,还有别的方法可以让我们可以更灵活地操作:使用时需要在xml文件中定义:

?
1
2
3
<framelayout android:id="@+id/fl1"
       android:layout_width="match_parent"
       android:layout_height="200dp"/>

在activity里面还需要做一点工作,因为我们必须手动初始化fragment,然后把它“插入”到framelayout中。

?
1
2
3
4
5
6
7
8
9
10
11
12
public class mainactivity extends activity {
 
@override
protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
 
  fragment2 f2 = new fragment2();
  fragmenttransaction ft = getfragmentmanager().begintransaction();
  ft.replace(r.id.fl1, f2);
  ft.commit();
}

例子

可以把fragment想象成activity的另外一种形式。你创建fragments去包含ui组件,就像创建activities那样。但是,fragment总是被嵌在activity中。

下面来通过一个例子看一下流程:

1.创建一个名为fragments的工程。
2.在res/layout文件夹下,新建一个叫fragment1.xml的文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#00ff00"
  android:orientation="vertical" >
 
  <textview
    android:id="@+id/lblfragment1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="this is fragment #1"
    android:textcolor="#000000"
    android:textsize="25sp" />
 
</linearlayout>

3.在res/layout文件夹下,新建一个叫fragment2.xml的文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#fffe00"
  android:orientation="vertical" >
 
  <textview
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="this is fragment #2"
    android:textcolor="#000000"
    android:textsize="25sp" />
 
  <button
    android:id="@+id/btngettext"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onclick="onclick"
    android:text="get text in fragment #1"
    android:textcolor="#000000" />
 
</linearlayout>

4.main.xml中的代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal" >
 
  <fragment
    android:id="@+id/fragment1"
    android:name="net.learn2develop.fragments.fragment1"
    android:layout_width="0px"
    android:layout_height="match_parent"
    android:layout_weight="1" />
 
  <fragment
    android:id="@+id/fragment2"
    android:name="net.learn2develop.fragments.fragment2"
    android:layout_width="0px"
    android:layout_height="match_parent"
    android:layout_weight="1" />
 
</linearlayout>

5.新建两个类:fragment1.java和fragment2.java。
6.fragment1.java中的代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package net.learn2develop.fragments;
 
import android.app.activity;
import android.app.fragment;
import android.os.bundle;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
 
public class fragment1 extends fragment {
  @override
  public view oncreateview(layoutinflater inflater, viewgroup container,
      bundle savedinstancestate) {
 
    log.d("fragment 1", "oncreateview");
 
    // ---inflate the layout for this fragment---
    return inflater.inflate(r.layout.fragment1, container, false);
  }
}

7.fragment2.java中的代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package net.learn2develop.fragments;
 
import android.app.fragment;
import android.os.bundle;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.button;
import android.widget.textview;
import android.widget.toast;
 
public class fragment2 extends fragment {
  @override
  public view oncreateview(layoutinflater inflater, viewgroup container,
      bundle savedinstancestate) {
    // ---inflate the layout for this fragment---
    return inflater.inflate(r.layout.fragment2, container, false);
  }
}