1.定义
    Fragment中文解释是碎片的意思,主要用在大屏幕设备上,例如平板电脑上,支持更加动态和灵活的UI设计。Fragment在你的应用中相当于是一个模块化和可重用的组件,因为Fragment定义了它自己的布局,以及通过使用它自己的生命周期回调方法定义了它自己的行为,你可以将Fragment包含到多个Activity中。
2.特点
(1)Fragment可以作为Activity界面的一部分组成出现;
(2)可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
(3)在Activity运行过程中,可以添加、移除或者替换Fragment;
(4)Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。
3.生命周期
Fragment必须是依存于Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。
生命周期中涉及的方法如上图所示,具体触发条件如下所述。
  • onAttach()

    • 当Fragment被添加到Activity时候会回调这个方法,并且只调用一次;
  • onCreate()
    • 创建Fragment时会回调,只会调用一次;
  • onActivityCreated()
    • 当Fragment所在的Activity启动完成后调用;
  • onCreateView()
    • 每次创建都会去绘制Fragment的View组件时回调该方法;
  • onStart()
    • 启动Fragment
  • onResume()
    • 恢复Fragment时会被回调,调用onStart()方法后面一定会调用onResume()方法;
  • onStop()
    • 停止Fragment
  • onDestroyView()
    • 销毁Fragment所包含的View组件时调用
  • onDestroy()
    • 销毁Fragment时被回调
  • onDetach()
    • Fragment从Activity中删除时会回调该方法,并且这个方法只会调用一次

4.静态加载

这是使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中,用布局文件调用Fragment。

(1)新建Fragment,重写onCreateView决定Fragment布局

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_static, container, false);
}

(2)在宿主Activity中手动添加Fragment,就把它当做普通的控件一样,在xml文件中使用。name属性填写fragment的包路径,Activity通过findFragmentById()或者findFragmentByTag()获取Fragment。

<fragment
android:name="ant.snail.com.fragmentactapp.StaticFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="newfrag" />

这样在宿主Activity中就能看到Fragment了。

5.动态加载

上面的静态加载是最基本的方法,下面解析下动态加载的原理。

(1)原理

  动态加载,顾名思义是通过代码的方式在Activity中加载Fragment。

  通过撰写代码将Fragment添加到一个Activity layout中,这里需要采用Fragment的事务处理(FragmentTransaction),有点类似数据库的事务处理。

  1. 根据用户的交互情况,对Fragment进行添加、移除、替换,以及执行其他动作,提交给Activity的每一套变化被称作一个事务;
  2. 每一个事务都是同时执行一套变化,可以再一个事务中设置你所有想执行的变化,包括add(),remove(),replace(),然后提交给Activity,最后调用commit()方法;
  3. 如果允许用户通过按下BACK按键返回到前一个Fragment状态,调用commit()之前可以加入addToBackStack()方法。

 (2)具体实现

  通过新建两个Fragment,并在这两个Fragment的Layout中添加了ImageView,用来放置图片,而在宿主Activity中将这两个Fragment动态切换,实现图片的自由切换。代码结构如下图所示。

新建Fragment(Image1Fragment,Image2Fragment),并添加了两个layout文件(fragment_image1,fragment_image2),其中部分代码如下:

Image1Fragmet代码:

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 获取Fragment的View
View view=inflater.inflate(R.layout.fragment_image1,container,false);
return view;
}

fragment_image1.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"
android:gravity="center_horizontal"
tools:context="ant.snail.com.fragmentactapp.Image1Fragment"
> <!-- TODO: Update blank fragment layout --> <LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
>
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是jin兔1"/> <Button
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="传递数据到主窗口"
android:id="@+id/btfr1" /> </LinearLayout> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView1"
android:src="@drawable/jin1"/>
</LinearLayout>

宿主MainActivity的代码如下,通过FragmentManager得到FragmentTransaction,然后通过replace()方法实现两个Fragment之间的切换,最后实现了Commit()方法:

 protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取两个按钮的View
bt1=(Button)findViewById(R.id.bt1);
bt2=(Button)findViewById(R.id.bt2); bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//主Activity动态加载Fragment
FragmentManager fragmentManager=getFragmentManager();
//处理Fragment事务
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//获取Image1Fragment实例
Image1Fragment image1Fragment=Image1Fragment.newInstance("Activity传递图片1到Fragment中");
//替换操作
beginTransaction.replace(R.id.imageLayout,image1Fragment);
//允许用户通过按下BACK按键返回到前一个Fragment状态
beginTransaction.addToBackStack(null);
beginTransaction.commit();
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//主Activity动态加载Fragment
FragmentManager fragmentManager=getFragmentManager();
//处理Fragment事务
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//获取Image1Fragment实例
Image2Fragment image2Fragment=Image2Fragment.newInstance("Activity传递图片2到Fragment中");
//替换操作
beginTransaction.replace(R.id.imageLayout,image2Fragment);
//允许用户通过按下BACK按键返回到前一个Fragment状态
beginTransaction.addToBackStack(null);
beginTransaction.commit();
}
}); }

其中NewInstance方法是在Fragment中实现的一个实例方法,用于将Fragment实例化,通过参数param1的传递能将Activity中的数据传递到Fragment中。通过setArguments()以及getArguments()实现数据从Activity向Fragment传递的目的,如下图所示。

 public static Image1Fragment newInstance(String param1) {
Image1Fragment fragment = new Image1Fragment();
//在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
  @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
//在Fragment中通过getArguments().getString()获取Activity传来的值
mParam1 = getArguments().getString(ARG_PARAM1);
}
}

6.Fragment与Activity通信

  • Fragment调用Activity里的数据

  在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法,此方法在上面的代码中已经介绍了。

  • Activity调用Fragment里的数据

  在Fragment中定义一个内部回调接口,让包含该Fragment的Activity实现该回调接口,这样Fragment可调用该回调方法将数据传递给Activity。下面主要实现在Activity调用Fragment的数据。

先在Fragment中定义一个内部回调接口:
  public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String uri);
}

在Fragment的onAttach()方法中将Activity转换为OnFragmentInteractionListener接口:

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
private OnFragmentInteractionListener mListener;
if (mListener != null) {
mListener.onFragmentInteraction("需要传递给Activity的值");
 

宿主Activity则需要实现此接口,并重写onFragmentInteraction(String uri)方法,这样就实现了数据从Fragment到Activity的传递:

public class MainActivity extends ActionBarActivity implements Image1Fragment.OnFragmentInteractionListener
@Override
public void onFragmentInteraction(String uri) {
TextView tv=(TextView)findViewById(R.id.tt);
tv.setText(uri);
}

7.效果截图

Android学习之Fragment解析的更多相关文章

  1. android学习笔记Fragment的使用

    Fragment的内容感觉好多啊,主要需要掌握Fragment静态加载,Fragment动态加载,Fragment的生命周期,Fragment与Activity的交互 1,Fragment的静态加载 ...

  2. Android学习——碎片Fragment的使用

    一.碎片的简单用法(实现在一个活动中添加两个碎片,并让这两个碎片平分活动空间) 1.新建一个FragmentTest项目: 新建一个左侧碎片布局left_fragment.xml,代码如下:(只放置一 ...

  3. Android学习笔记- Fragment实例 底部导航栏的实现

    1.要实现的效果图以及工程目录结构: 先看看效果图吧: 接着看看我们的工程的目录结构: 2.实现流程: Step 1:写下底部选项的一些资源文件 我们从图上可以看到,我们底部的每一项点击的时候都有不同 ...

  4. [Android学习笔记]Fragment使用

    一.android.app.Fragment 与 android.support.v4.app.Fragment 区别 support.v4.app.Fragment是为了给低版本Android使用的 ...

  5. Android学习笔记 - BitmapFun解析

    如果图片资源是静态的,当我们要在View上显示图片时,只需要简单的将图片赋值给ImageView就可以了,但如果需要浏览网络上的图片时该如何做呢?有可能图片很大,有可能网速很慢并且不稳定,这种情况下该 ...

  6. 【转】 Pro Android学习笔记(四三):Fragment(8):再谈Transaction和管理器

    目录(?)[-] Transaction的一些操作 再谈FragmentManager 调用其他fragment的方法 唤起activity 唤起fragment和相互通信 一些其它 Transact ...

  7. 【转】 Pro Android学习笔记(四二):Fragment(7):切换效果

    目录(?)[-] 利用setTransition 利用setCustomAnimations 通过ObjectAnimator自定义动态效果 程序代码的编写 利用fragment transactio ...

  8. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

  9. 【转】 Pro Android学习笔记(四一):Fragment(6):数据保留

    目录(?)[-] 通过fragment参数实现数据保留 对TitleFragment进行修改 对DetailActivity进行修改 通过savedInstanceState进行数据保留 保留frag ...

随机推荐

  1. 4-计算九位数以内各个位数字和为s的种类

    /*假设我们当前要求的是100以内各位数之和和等于s的数有多少个,可以想到就是10以内各位数之和等于s的数的个数再加上10到100内的各位数之和等于s的个数.令dp[i][j]就代表10的j次方内各位 ...

  2. springmvc中Controller方法的返回值

    1.1 返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加model数据.指定view. 1.2 返回void 在controller方法形参 ...

  3. loadrunner12-运行报错原因及解决办法整理集合

    1.错误:已超过该load generator的CPU使用率80%: 答:机器内存过小,更换配置更好的机器来执行测试. 是因为虚机的内存过小,运行Controller需要消耗的CPU过高,超过了80% ...

  4. @RequestMapping 介绍

    RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestMapping注解有六个属性,下面我们把她 ...

  5. win10如何安装和创建 证书

    .下载winsdksetup.exe .在 MMC 管理单元中查看证书 打开一个命令提示符窗口. 类型mmc然后按 ENTER 键. 请注意,若要查看本地计算机存储中的证书,您必须具有管理员角色. 上 ...

  6. 讲讲我在Windows10(uwp)开发中遇到的一些坑.

    7月29日发布的Windows10正式版,当天安装好以后,在网络不太好的情况下,经过多次尝试终于装上了Visual Studio 2015和Windows 10 10240的SDK.这两周一直在开发U ...

  7. Devexpress VCL Build v2013 vol 13.2.4 发布

    不说了,自己看吧. What's New in 13.2.4 (VCL Product Line)   New Major Features in 13.2 What's New in VCL Pro ...

  8. 2018.10.18 NOIP训练 [SCOI2018]Pipi 酱的日常(线段树)

    传送门 线段树好题啊. 题目要求的是sum−a−b−c+maxsum-a-b-c+maxsum−a−b−c+max{∣a+v∣+∣b+v∣+∣c+v∣|a+v|+|b+v|+|c+v|∣a+v∣+∣b ...

  9. 2018.09.16 bzoj1176: [Balkan2007]Mokia(cdq分治)

    传送门 调了半天发现是输出优化打错了求心理阴影体积233 这题很简单啊. 一个修改操作x如果对一个询问操作y有贡献那么有. tx<ty,Xx<=Xy,Yx<=Yy" rol ...

  10. 2018.08.04 洛谷P3380 【模板】二逼平衡树(树套树)

    传送门 技不如人,写的权值线段树套线段树在bzoj上无论如何都卡不过空间. 这是一道树套树简单题,感觉没什么好说的. 直接权值线段树套平衡树就行了. 代码: #include<bits/stdc ...