前面一起学习了Fragment的创建和加载,以及其生命周期方法,那么接下来进一步来学习Fragment的具体使用,本期先来学习Fragment添加、删除、替换。

一、概述

在前面的学习中,特别是动态加载的时候,有提到FragmentManager和FragmentTransaction类,这里先来详细了解一下其到底为何物。

1、FragmentManager

要管理Activity中的Fragments,就需要使用FragmentManager类。通过getFragmentManager()或getSupportFragmentManager()获得 。

FragmentManager类常用的方法有以下几个:

  • findFragmentById(int id):根据ID来找到对应的Fragment实例,主要用在静态添加Fragment的布局中,因为静态添加的Fragment才会有ID 。

  • findFragmentByTag(String tag):根据TAG找到对应的Fragment实例,主要用于在动态添加的Fragment中,根据TAG来找到Fragment实例 。

  • getFragments():获取所有被add进Activity中的Fragment 实例。

  • benginTransatcion():开启一个事物。

2、FragmentTransaction

如果需要添加、删除、替换Fragment,则需要借助于FragmentTransaction对象,FragmentTransaction 代表 Activity 对 Fragment 执行的多个改变。

FragmentTransaction类常用的方法有以下几个:

  • add(int containerViewId, Fragment fragment, String tag):将一个Fragment实例添加到Activity的最上层 。

  • remove(Fragment fragment):将一个Fragment实例从Activity的Fragment队列中删除。

  • replace(int containerViewId, Fragment fragment):替换containerViewId中的Fragment实例。注意,它首先把containerViewId中所有Fagment删除,然后再add进去当前的Fragment 实例。

  • hide(Fragment fragment):隐藏当前的Fragment,仅仅是设为不可见,并不会销毁。

  • show(Fragment fragment):显示之前隐藏的Fragment。

  • detach(Fragment fragment):会将view从UI中移除,和remove()不同,此时Fragment的状态依然由FragmentManager维护。

  • attach(Fragment fragment):重建view视图,附加到UI上并显示。

  • commit():提交一个事务。

二、示例

前面了解了Fragment管理和事物,为了更好的理解和掌握,用一个示例来进一步深度学习。

该示例非常简单,界面包含3个按钮和3个Fragment容器,其中第一个容器静态加载FirstFragment,后面两个通过动态加载的方式来完成,也是本示例主要需要学习的地方。

首先创建第一个容器的FirstFragment对应布局文件fragment_first.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:background="#af520b"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是我的第一个Fragment"
android:textColor="#0c1ff1"
android:textSize="18sp"/> </LinearLayout>

接着创建第一个容器的FirstFragment文件,代码如下:

package com.cqkxzsxy.jinyu.android.fragmentbasemanager;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; public class FirstFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
return view;
}
}

同理创建fragment_second.xml和fragment_third.xml文件,唯一的区别就是显示的提示文字和颜色不同,创建SecondFragment和ThirdFragment加载对应的布局文件,这里不在给出代码。

然后是修改activity_main.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"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/add_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" /> <Button
android:id="@+id/remove_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="remove" /> <Button
android:id="@+id/replace_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="replace" />
</LinearLayout> <fragment
android:id="@+id/fragment_one"
android:name="com.cqkxzsxy.jinyu.android.fragmentbasemanager.FirstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <FrameLayout
android:id="@+id/fragment_container1"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <FrameLayout
android:id="@+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </LinearLayout>

最后是修改MainActivity的代码,如下所示:

package com.cqkxzsxy.jinyu.android.fragmentbasemanager;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mAddBtn = null;
private Button mRemoveBtn = null;
private Button mReplaceBtn = null;
private Fragment mSecondFragment = null;
private Fragment mThirdFragment = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mAddBtn = (Button) findViewById(R.id.add_btn);
mRemoveBtn = (Button) findViewById(R.id.remove_btn);
mReplaceBtn = (Button) findViewById(R.id.replace_btn); // 创建和获取Fragment实例
mSecondFragment = new SecondFragment();
mThirdFragment = new ThirdFragment(); // 设置监听事件
mAddBtn.setOnClickListener(this);
mRemoveBtn.setOnClickListener(this);
mReplaceBtn.setOnClickListener(this);
} @Override
public void onClick(View v) {
// 获取到FragmentManager对象
FragmentManager fragmentManager = getFragmentManager();
// 开启一个事务
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // Fragment操作
switch (v.getId()) {
case R.id.add_btn:
// 向容器内加入Fragment
if (!mSecondFragment.isAdded()) {
fragmentTransaction.add(R.id.fragment_container1, mSecondFragment);
}
if (!mThirdFragment.isAdded()) {
fragmentTransaction.add(R.id.fragment_container2, mThirdFragment);
}
break;
case R.id.remove_btn:
// 从容器类移除Fragment
fragmentTransaction.remove(mSecondFragment);
break;
case R.id.replace_btn:
if (!mSecondFragment.isAdded()) {
fragmentTransaction.replace(R.id.fragment_container2, mSecondFragment);
}
break;
default:
break;
} // 提交事务
fragmentTransaction.commit();
}
}

主要就是为3个按钮设置监听事件,其中第一个按钮为后2个容器添加Fragment,第二个按钮移除第一个容器的Fragment,第三个按钮将容器2里面的Fragment替换。

运行程序可以看到下图所示界面,首先点击“ADD”按钮,将SecondFragment和ThirdFragment动态添加到相应容器。

然后点击“REMOVE”将SecondFragment移除,可以看到SecondFragment被移除,ThirdFragment的位置上移;再点击“REPLACE”按钮将本来加载了ThirdFragment的第二个容器替换为SecondFragment,可以看到替换效果;最后再点击“REMOVE”重新将SecondFragment移除,可以看到最后只剩下FirstFragment。

通过上面的操作相信你应该简单知道如何添加、移除和替换Fragment了。这里有个值得注意的问题是很多同学分不清add操作和replace操作,接下来继续在上面的案例基础上进行修改验证。

在SecondFragment和ThirdFragment中加入Fragment的生命周期方法,同时加入Logcat日志,然后重新运行程序。首先点击“ADD”按钮,将SecondFragment和ThirdFragment动态添加到相应容器。打开Logcat日志可以看到:

然后点击“REMOVE”将SecondFragment移除,再点击“REPLACE”按钮将本来加载了ThirdFragment的第二个容器替换为SecondFragment。打开Logcat日志可以看到:

从上面的2个日志信息可以论证前面所讲的,replace是首先把containerViewId中所有Fagment删除,然后再add进去当前的Fragment 实例。

今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

如果该系列分享对你有帮助,就动动手指关注、点赞、留言吧,你的互动就是对我最大的鼓励!

此文章版权为微信公众号分享达人秀(ShareExpert)——鑫鱻所有,若需转载请联系作者授权,特此声明!

往期总结回顾:

Android零基础入门第1节:Android的前世今生

Android零基础入门第2节:Android 系统架构和应用组件那些事

Android零基础入门第3节:带你一起来聊一聊Android开发环境

Android零基础入门第4节:正确安装和配置JDK, 高富帅养成第一招

Android零基础入门第5节:善用ADT Bundle, 轻松邂逅女神

Android零基础入门第6节:配置优化SDK Manager, 正式约会女神

Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点

Android零基础入门第9节:Android应用实战,不懂代码也可以开发

Android零基础入门第10节:开发IDE大升级,终于迎来了Android Studio

Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌

Android零基础入门第13节:Android Studio个性化配置,打造开发利器

Android零基础入门第14节:使用高速Genymotion,跨入火箭时代

Android零基础入门第15节:掌握Android Studio项目结构,扬帆起航

Android零基础入门第16节:Android用户界面开发概述

Android零基础入门第17节:文本框TextView

Android零基础入门第18节:输入框EditText

Android零基础入门第19节:按钮Button

Android零基础入门第20节:复选框CheckBox和单选按钮RadioButton

Android零基础入门第21节:开关组件ToggleButton和Switch

Android零基础入门第22节:图像视图ImageView

Android零基础入门第23节:图像按钮ImageButton和缩放按钮ZoomButton

Android零基础入门第24节:自定义View简单使用,打造属于你的控件

Android零基础入门第25节:简单且最常用的LinearLayout线性布局

Android零基础入门第26节:两种对齐方式,layout_gravity和gravity大不同

Android零基础入门第27节:正确使用padding和margin

Android零基础入门第28节:轻松掌握RelativeLayout相对布局

Android零基础入门第29节:善用TableLayout表格布局

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

Android零基础入门第31节:少用的AbsoluteLayout绝对布局

Android零基础入门第32节:新推出的GridLayout网格布局

Android零基础入门第33节:Android事件处理概述

Android零基础入门第34节:Android中基于监听的事件处理

Android零基础入门第35节:Android中基于回调的事件处理

Android零基础入门第36节:Android系统事件的处理

Android零基础入门第37节:初识ListView

Android零基础入门第38节:初识Adapter

Android零基础入门第39节:ListActivity和自定义列表项

Android零基础入门第40节:自定义ArrayAdapter

Android零基础入门第41节:使用SimpleAdapter

Android零基础入门第42节:自定义BaseAdapter

Android零基础入门第43节:ListView优化和列表首尾使用

Android零基础入门第44节:ListView数据动态更新

Android零基础入门第45节:网格视图GridView

Android零基础入门第46节:列表选项框Spinner

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

Android零基础入门第48节:可折叠列表ExpandableListView

Android零基础入门第49节:AdapterViewFlipper图片轮播

Android零基础入门第50节:StackView卡片堆叠

Android零基础入门第51节:进度条ProgressBar

Android零基础入门第52节:自定义ProgressBar炫酷进度条

Android零基础入门第53节:拖动条SeekBar和星级评分条RatingBar

Android零基础入门第54节:视图切换组件ViewSwitcher

Android零基础入门第55节:ImageSwitcher和TextSwitcher

Android零基础入门第56节:翻转视图ViewFlipper

Android零基础入门第57节:DatePicker和TimePicker选择器

Android零基础入门第58节:数值选择器NumberPicker

Android零基础入门第59节:常用三大Clock时钟组件

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

Android零基础入门第61节:滚动视图ScrollView

Android零基础入门第62节:搜索框组件SearchView

Android零基础入门第63节:值得借鉴学习的选项卡TabHost

Android零基础入门第64节:揭开RecyclerView庐山真面目

Android零基础入门第65节:RecyclerView分割线开发技巧

Android零基础入门第66节:RecyclerView点击事件处理

Android零基础入门第67节:RecyclerView数据动态更新

Android零基础入门第68节:RecyclerView添加首尾视图

Android零基础入门第69节:ViewPager快速实现引导页

Android零基础入门第70节:ViewPager打造TabHost效果

Android零基础入门第71节:CardView简单实现卡片式布局

Android零基础入门第72节:SwipeRefreshLayout下拉刷新

Android零基础入门第73节:Activity创建和配置

Android零基础入门第74节:Activity启动和关闭

Android零基础入门第75节:Activity状态和生命周期

Android零基础入门第76节:Activity数据保存和横竖屏切换

Android零基础入门第77节:Activity任务栈和启动模式

Android零基础入门第78节:四大组件的纽带——Intent

Android零基础入门第79节:Intent 属性详解(上)

Android零基础入门第80节:Intent 属性详解(下)

Android零基础入门第81节:Activity数据传递

Android零基础入门第82节:Activity数据回传

Android零基础入门第83节:Activity间数据传递方法汇总

Android零基础入门第84节:引入Fragment原来是这么回事

Android零基础入门第85节:Fragment使用起来如此简单

Android零基础入门第86节:探究Fragment生命周期

Android零基础入门第87节:Fragment添加、删除、替换的更多相关文章

  1. Android零基础入门第89节:Fragment回退栈及弹出方法

    在上一期分享的文章末尾留了一个课后作业,有去思考如何解决吗?如果已经会了那么恭喜你,如果还不会也没关系,本期一起来学习. 一.回退栈 在前面两期的示例中,当我们完成一些操作后,如果想要回到操作之前的状 ...

  2. Android零基础入门第88节:Fragment显示和隐藏、绑定和解绑

    在上一期我们学习了FragmentManager和FragmentTransaction的作用,并用案例学习了Fragment的添加.移除和替换,本期一起来学习Fragment显示和隐藏.绑定和解绑. ...

  3. Android零基础入门第86节:探究Fragment生命周期

    一个Activity可以同时组合多个Fragment,一个Fragment也可被多个Activity 复用.Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的 ...

  4. Android零基础入门第85节:Fragment使用起来非常简单

    Fragment创建完成后并不能单独使用,还需要将Fragment加载到Activity中,在Activity中添加Fragment的方式有两种:静态加载和动态加载,接下来分别进行学习. 一.静态加载 ...

  5. Android零基础入门第84节:引入Fragment原来是这么回事

    随着大众生活水平的提高,再加上移动互联网的迅速发展,几乎每个人都至少拥有一台搭载Android系统的移动设备.Android设备的多样性给我们带来了很大的便捷,各Android设备拥有不同分辨率和不同 ...

  6. Android零基础入门第63节:过时但仍值得学习的选项卡TabHost

    原文:Android零基础入门第63节:过时但仍值得学习的选项卡TabHost 由于前几天参加一个学习培训活动,几乎每天都要从早晨7点到晚上一两点,没有什么时间来分享,实在抱歉中间断更了几天.从今天开 ...

  7. Android零基础入门第73节:Activity初入门,创建和配置如此简单

    Activity是Android应用的重要组成单元之一,也是Android应用最常见的组件之一.前面看到的示例通常都只包含一个Activity或一个AppCompatActivity,但在实际应用中这 ...

  8. Android零基础入门第70节:ViewPager轻松完成TabHost效果

    上一期学习了ViewPager的简单使用,本期一起来学习ViewPager的更多用法. 相信很多同学都使用过今日头条APP吧,一打开主界面就可以看到顶部有很多Tab,然后通过左右滑动来切换,就可以通过 ...

  9. Android零基础入门第29节:善用TableLayout表格布局,事半功倍

    原文:Android零基础入门第29节:善用TableLayout表格布局,事半功倍 前面学习了线性布局和相对布局,线性布局虽然方便,但如果遇到控件需要排列整齐的情况就很难达到要求,用相对布局又比较麻 ...

随机推荐

  1. jQuery+ localStorage 实现一个简易的计时器

    原型 图片发自简书App 需求1.关闭浏览器时时间继续运行2.刷新时保持当前状态3.结束时间保存在客户端 <div class="wrapper"> <div c ...

  2. 课堂随笔02--c#中string作为引用类型的特殊性

    using System; namespace Test { class Test1 { static void Main(string[] args) { string str1 = "1 ...

  3. 创建数据库以及其属性的sql语句

    创建数据库的SQL语句: create database stuDB on primary -- 默认就属于primary文件组,可省略 ( /*--数据文件的详细描写叙述--*/ name='stu ...

  4. Java对象基础的一些小问题

    1 权限修饰符public protected private default..访问权限修饰符   public protected default private 同类 T T T T 同包 T ...

  5. Java数组定义学习的一些随笔

    //一维数组的定义 int[] arr1 = new int[3];//arr1 = {1,2,3}: 错误 int[] arr2 = new int[]{1,2,3};//int[] arr2 = ...

  6. 【codeforces 785C】Anton and Fairy Tale

    [题目链接]:http://codeforces.com/contest/785/problem/C [题意] 容量为n的谷仓,每一天都会有m个谷子入仓(满了就视为m);第i天 会有i只鸟叼走i个谷子 ...

  7. WM_NOTIFY消息流程实例分析

    我们以CListCtrl控件为例来分析WM_NOTIFY消息. CListCtrl控件在Report样式下会包含CHeaderCtrl标头控件,即CHeaderCtrl标头控件为CListCtrl控件 ...

  8. C#实现拼图游戏

    C#实现<拼图游戏> (下) 原理篇   前言:在 http://www.cnblogs.com/labixiaohei/p/6698887.html 程序设计 之 C#实现<拼图游 ...

  9. 一组西门子S7 报文

    03 00 00 16 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A(第一次握手报文) 03 00 00 16 11 D0 00 01 0 ...

  10. options.parse === void 0

    if (options.parse === void 0) options.parse = true; https://developer.mozilla.org/zh-CN/docs/Web/Jav ...