欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Fragment 基本了解(图文介绍)

程序员文章站 2023-12-01 08:30:04
fragment android是在android 3.0 (api level 11)开始引入fragment的。 可以把fragment想成activity中的模块,这...
fragment
android是在android 3.0 (api level 11)开始引入fragment的。
可以把fragment想成activity中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,在activity运行的时候可以加载或者移除fragment模块。
可以把fragment设计成可以在多个activity中复用的模块。
当开发的应用程序同时适用于平板电脑和手机时,可以利用fragment实现灵活的布局,改善用户体验。
如图:
Android Fragment 基本了解(图文介绍) 
fragment的生命周期
因为fragment必须嵌入在acitivity中使用,所以fragment的生命周期和它所在的activity是密切相关的。
如果activity是暂停状态,其中所有的fragment都是暂停状态;如果activity是stopped状态,这个activity中所有的fragment都不能被启动;如果activity被销毁,那么它其中的所有fragment都会被销毁。
但是,当activity在活动状态,可以独立控制fragment的状态,比如加上或者移除fragment。
当这样进行fragment transaction(转换)的时候,可以把fragment放入activity的back stack中,这样用户就可以进行返回操作。
Android Fragment 基本了解(图文介绍) 
fragment的使用相关
使用fragment时,需要继承fragment或者fragment的子类(dialogfragment, listfragment, preferencefragment, webviewfragment),所以fragment的代码看起来和activity的类似。
使用support library
support library是一个提供了api库函数的jar文件,这样就可以在旧版本的android上使用一些新版本的apis。
比如android-support-v4.jar.它的完整路径是:
<sdk>/extras/android/support/v4/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.
Android Fragment 基本了解(图文介绍) 
当创建包含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布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。
加载方式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。
加载方式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实例的改变生效。
实例
练习的例子:
写一个类继承自fragment类,并且写好其布局文件(本例中是两个textview),在fragment类的oncreateview()方法中加入该布局。
之后用两种方法在activity中加入这个fragment:
第一种是在activity的布局文件中加入<fragment>标签;
第二种是在activity的代码中使用fragmenttransaction的add()方法加入fragment。
贴出代码:
自己定义的fragment类: 
复制代码 代码如下:

examplefragment.java
package com.example.learningfragment;
import android.os.bundle;
import android.support.v4.app.fragment;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
public class examplefragment extends fragment
{
//三个一般必须重载的方法
@override
public void oncreate(bundle savedinstancestate)
{
// todo auto-generated method stub
super.oncreate(savedinstancestate);
system.out.println("examplefragment--oncreate");
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate)
{
system.out.println("examplefragment--oncreateview");
return inflater.inflate(r.layout.example_fragment_layout, container, false);
}
@override
public void onpause()
{
// todo auto-generated method stub
super.onpause();
system.out.println("examplefragment--onpause");
}
@override
public void onresume()
{
// todo auto-generated method stub
super.onresume();
system.out.println("examplefragment--onresume");
}
@override
public void onstop()
{
// todo auto-generated method stub
super.onstop();
system.out.println("examplefragment--onstop");
}
}

fragment的布局文件
复制代码 代码如下:

example_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/num1"
/>
<textview
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/num2"
/>
</linearlayout>

主activity
复制代码 代码如下:

learnfragment.java
package com.example.learningfragment;
import android.os.bundle;
import android.support.v4.app.fragmentactivity;
import android.support.v4.app.fragmentmanager;
import android.support.v4.app.fragmenttransaction;
public class learnfragment extends fragmentactivity
{
@override
public void oncreate(bundle savedinstancestate)
{
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_learn_fragment);
//在程序中加入fragment
fragmentmanager fragmentmanager = getsupportfragmentmanager();
fragmenttransaction fragmenttransaction = fragmentmanager.begintransaction();
examplefragment fragment = new examplefragment();
fragmenttransaction.add(r.id.linear, fragment);
fragmenttransaction.commit();
}
}

activity的布局文件
复制代码 代码如下:

activity_learn_fragment.xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<button
android:id="@+id/btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn1"
/>
<fragment
android:name="com.example.learningfragment.examplefragment"
android:id="@+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<button
android:id="@+id/btn2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn2"
/>
<linearlayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<button
android:id="@+id/btn3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn3"
/>
</linearlayout>
</linearlayout>

运行结果如下:
Android Fragment 基本了解(图文介绍)可以看到第二种方式加入fragment的时候,指定了父容器(一个线性布局)的id,其中已经有一个button 3,所以fragment加在其后。
参考资源
fragment类文档:
http://developer.android.com/reference/android/app/fragment.html
training:building a dynamic ui with fragments
http://developer.android.com/training/basics/fragments/index.html
fragments develop guide:
http://developer.android.com/guide/components/fragments.html