一、概述
每一个Activiy都有一个Fragment的管理器FragmentManager来管理包含的Fragment。在API 11以上可以通过getFragmentManager();来获取,在API 11 以下,需要继承V4包中的FragmentActivity,可以通过调用getSupportFragmentManager();来获取。Fragment Manager就可以来管理Fragment了,而且提供了FragmentTransaction来添加移除替换Fragment。
Fragment在使用的时候分为静态调用和动态加载两种方式。
二、Fragment静态调用
Fragment静态调用比较简单,只需要在Activity的布局中使用fragment标签即可。有一点需要注意的是Android在3.0(API 11)之后提出的Fragment,所以为了支持3.0以下系统的设备,Google一支持包的方式来向下兼容。但是支持包内的和系统的是两套相对独立的代码,不可混淆使用。下面通过示例来进行Fragment静态调用用法的说明,首先瞄一眼最后实现的效果。
1. 系统Fragment静态调用
使用系统Fragment需要最低版本为11,在适配低版本手机的时候通常不采用这种方式,随着3.0以后版本占市场绝大对数之后应该会变为主流的方式。
(1). 创建Activity继承android.app.Activity
package com.kevin.fragmentlearn03.activity;
import com.kevin.fragmentlearn03.R;
import android.app.Activity;
import android.os.Bundle;
public class AppActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app);
}
}
这里和我们之前写Activity都是一样的,继承自android.app.Activity。
(2). 创建Fragment继承android.app.Fragmentpackage com.kevin.fragmentlearn03.view;
import com.kevin.fragmentlearn03.R;
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_app, null);
}
}
创建我们自己的Fragment继承自android.app.Fragment,重写onCreatView()方法,为什么要重写这个方法,在《Fragment学习之一、Fragment生命周期》中已经讲过,该生命周期方法就是填充该Fragment显示内容的。说直白点就是我们想要这个Fragment显示什么布局就在这里设置布局文件。
(3). 添加fragment标签到布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/app_fragment"
android:name="com.kevin.fragmentlearn03.view.AppFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
把我们创建的Fragment添加到宿主Activity,只需要在该宿主Activity的布局文件引用创建的Fragment即可,添加fragment标签,并且设置标签的name属性为所创建的Fragment类全名称。
2. V4包Fragment静态调用
(1). 创建Activity继承android.support.v4.app.FragmentActivity
package com.kevin.fragmentlearn03.activity;
import com.kevin.fragmentlearn03.R;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class AppV4Activity extends FragmentActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_v4_app);
}
}
与平时创建Activity不同的一点就是这里继承的不是android.app.Activity 而是android.support.v4.app.Activity。也很好理解,在3.0之前的Activity类中是没有操作Fragment的FragmentManager的,Google在支持包为我们提供好了。
(2). 创建Fragment继承android.support.v4.app.Fragment
package com.kevin.fragmentlearn03.view;
import com.kevin.fragmentlearn03.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppV4Fragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_v4_app, null);
}
}
上面的Fragment和之前创建的Fragment在代码上完全一致,只不过是这个导入android.support.v4.app.Fragment包,上一个导入android.app.Fragment包。填充的布局也比较简单,都为相对布局内包裹一个TextView。
(3). 添加fragment标签到布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/app_v4_fragment"
android:name="com.kevin.fragmentlearn03.view.AppV4Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
这里和上面添加fragment标签相同。
至此Fragment静态调用以及向下兼容就讲解完了,然后继续分析Fragment的动态加载。
三、Fragment动态加载
下面通过示例来进行Fragment动态加载用法的说明,先来看一下最终实现的效果。
1. 系统Fragment动态加载
(1). 创建Activity继承android.app.Activity
package com.kevin.fragmentlearn04.activity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import com.kevin.fragmentlearn04.R;
@SuppressLint("NewApi")
public class AppActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏系统标题栏
setContentView(R.layout.activity_app);
}
}
(2). 编写Activity布局文件
<?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="48dip"
android:background="#8866FF00"
android:gravity="center"
android:text="@string/fragment_app_title"
android:textSize="22sp" />
<FrameLayout
android:id="@+id/fragment_app_contect"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
……
</LinearLayout>
这里底部的四个按键就不写上了,很简答上面为FrameLayout,底部为三个按钮。
(3). 创建Fragment继承android.app.Fragment
package com.kevin.fragmentlearn04.fragment;
import com.kevin.fragmentlearn04.R;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppFragmentContact extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
复写了onCreateView来初始化布局,在onViewCreated里面来对布局事件处理。
(4). Activity内动态切换Fragment
package com.kevin.fragmentlearn04.activity;
import com.kevin.fragmentlearn04.R;
import com.kevin.fragmentlearn04.fragment.AppFragmentContact;
import com.kevin.fragmentlearn04.fragment.AppFragmentDynamic;
import com.kevin.fragmentlearn04.fragment.AppFragmentMessage;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
public class AppActivity extends Activity implements OnClickListener{
//……省略部分代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏系统标题栏
setContentView(R.layout.activity_app);
initViews();
initEvents();
// 初始化Fragment Manager
fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragment_app_contect, new AppFragmentMessage());
ft.commit();
}
//……省略部分代码
@Override
public void onClick(View v) {
// 开启Fragment事务
ft = fragmentManager.beginTransaction();
switch (v.getId()) {
case R.id.btn_app_act_message:
mAppFragmentMessage = mAppFragmentMessage == null ? new AppFragmentMessage() : mAppFragmentMessage;
// 用Fragment替换 fragment_app_contect 控件
ft.replace(R.id.fragment_app_contect, mAppFragmentMessage);
// 事务提交
ft.commit();
break;
case R.id.btn_app_act_contact:
mAppFragmentContact = mAppFragmentContact == null ? new AppFragmentContact() : mAppFragmentContact;
// 用Fragment替换 fragment_app_contect 控件
ft.replace(R.id.fragment_app_contect, mAppFragmentContact);
// 事务提交
ft.commit();
break;
case R.id.btn_app_act_dynamic:
mAppFragmentDynamic = mAppFragmentDynamic == null ? new AppFragmentDynamic() : mAppFragmentDynamic;
// 用Fragment替换 fragment_app_contect 控件
ft.replace(R.id.fragment_app_contect, mAppFragmentDynamic);
// 事务提交
ft.commit();
break;
}
}
}
2. V4包Fragment动态加载
(1). 创建Activity继承android.support.v4.app.FragmentActivity
package com.kevin.fragmentlearn04.activity;
import com.kevin.fragmentlearn04.R;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Window;
public class AppV4Activity extends FragmentActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏系统标题栏
setContentView(R.layout.activity_v4_app);
}
}
(2). 编写Activity布局文件
<?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="48dip"
android:background="#8866FF00"
android:gravity="center"
android:text="@string/fragment_app_title"
android:textSize="22sp" />
<FrameLayout
android:id="@+id/fragment_app_contect"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
……
</LinearLayout>
(3). 创建Fragment继承android.support.v4.app.Fragment
package com.kevin.fragmentlearn04.fragment;
import com.kevin.fragmentlearn04.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppV4FragmentContact extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
(4). Activity内动态切换Fragment
package com.kevin.fragmentlearn04.activity;
import com.kevin.fragmentlearn04.R;
import com.kevin.fragmentlearn04.fragment.AppV4FragmentContact;
import com.kevin.fragmentlearn04.fragment.AppV4FragmentDynamic;
import com.kevin.fragmentlearn04.fragment.AppV4FragmentMessage;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
/**
* 版权所有:----有限公司</br>
*
* MainActivity </br>
*
* @author zhou.wenkai ,Created on 2015-4-16 14:51:45</br>
* Major Function:V4包Fragment动态加载</br>
*
* 注:如果您修改了本类请填写以下内容作为记录,如非本人操作劳烦通知,谢谢!!!</br>
* @author mender,Modified Date Modify Content:
*/
public class AppV4Activity extends FragmentActivity implements OnClickListener{
//……省略部分代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏系统标题栏
setContentView(R.layout.activity_v4_app);
initViews();
initEvents();
fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragment_app_contect, new AppV4FragmentMessage());
ft.commit();
}
//……省略部分代码
@Override
public void onClick(View v) {
// 开启Fragment事务
ft = fragmentManager.beginTransaction();
switch (v.getId()) {
case R.id.btn_app_act_message:
mAppV4FragmentMessage = mAppV4FragmentMessage == null ? new AppV4FragmentMessage() : mAppV4FragmentMessage;
ft.replace(R.id.fragment_app_contect, mAppV4FragmentMessage);
// 提交Fragment事务
ft.commit();
break;
case R.id.btn_app_act_contact:
mAppV4FragmentContact = mAppV4FragmentContact == null ? new AppV4FragmentContact() : mAppV4FragmentContact;
ft.replace(R.id.fragment_app_contect, new AppV4FragmentContact());
// 提交Fragment事务
ft.commit();
break;
case R.id.btn_app_act_dynamic:
mAppV4FragmentDynamic = mAppV4FragmentDynamic == null ? new AppV4FragmentDynamic() : mAppV4FragmentDynamic;
ft.replace(R.id.fragment_app_contect, mAppV4FragmentDynamic);
// 提交Fragment事务
ft.commit();
break;
}
}
}
四、总结
该文主要介绍了Fragment的静态调用以及动态加载的简单使用。以下做下总结:
1. Fragment静态调用
(1). 继承系统Fragment
①. 创建我们的AppActivity继承android.app.Activity;
②. 创建我们的AppFragment继承android.app.Fragment;
③. 在AppActivity的布局文件添加fragment标签,name属性为AppFragment类全名。
(2). 继承V4包Fragment
①. 创建我们的AppV4Activity继承android.support.v4.app.FragmentActivity;
②. 创建我们的AppV4Fragment继承android.support.v4.app.Fragment;
③. 在AppV4Activity的布局文件添加fragment标签,name属性为AppV4Fragment类全名。
2. Fragment动态加载
(1). 继承系统Fragment
①. 创建我们的Activity继承android.app.Activity;
②. 编写Activity的布局;
③. 创建Fragment继承android.app.Fragment;
④. Activity内通过getFragmentManager()获取FragmentManager然后开启事务动态加载Fragment。
(2). 继承V4包Fragment
①. 创建我们的Activity继承android.support.v4.app.Activity;
②. 编写Activity的布局;
③. 创建Fragment继承android.support.v4.app.Fragment;
④. Activity内通过getSupportFragmentManager()获取FragmentManager然后开启事务动态加载Fragment。
3. Fragment常用知识点
(1). 相关类
①. android.support.v4.app.FragementActivity向下兼容的Fragment的Activity;
②.android.support.v4.app.Fragment、android.app.Fragment 用于创建Fragment,其中android.app.Fragment要求最低版本为API 11,android.support.v4.app.Fragment作向下兼容;
③. android.support.v4.app.FragmentTransaction、android.app.FragmentTransaction用于Fragment的原子操作,用过数据库的朋友应该很熟悉;
(2). FragmentManager获取方式
①. Activity继承Activity:FragmentManagerfragmentManager = getFragmentManager();
②. Activity继承自FragmentActivity:FragmentManagerfragmentManager = getSupportFragmentManager();
(3). FragmentTransaction事务操作方法
①.开启事务:FragmentTransaction ft = fragmentManager.beginTransaction();
②.添加Fragment:ft.add();
③.隐藏Fragment:ft.hide();
④. 显示Fragment:ft.show();
⑤.移除Fragment:ft.remove();
⑥.替换Fragment:ft.replace();
⑦.提交事务:ft.commit();