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. springmvc与struts2的不同

    1.springmv的入口是一个servlet,即前端控制器.而struts2入口是一个fliter过滤器. 2.springmvc是基于开发方法(一个url对应一个方法,通过注解的方式进行访问),请 ...

  2. db2 查看表空间使用率

    1. 统计所有节点表空间使用率 select substr(TABLESPACE_NAME,1,20) as TBSPC_NAME,bigint(TOTAL_PAGES * PAGE_SIZE)/10 ...

  3. CComSafeArray

    https://blog.csdn.net/tangaowen/article/details/6554640

  4. 1.struts 防止表单重复提交 2. 拦截器

    1. 使用struts 防止表单提交 时, form 表单必须使用struts标签库编写,如<s:form/> 等,而不是html标签 2. 拦截器是struts2的核心.  interc ...

  5. hadoop 学习(二)ubuntu hadoop 2.7.0 伪分部安装

    本篇是基于上一篇,ubuntu 安装hadoop单机版基础上的 1.配置core-site.xml /usr/local/hadoop/etc/hadoop/core-site.xml 包含了hado ...

  6. c++中类的静态成员对象

    在c++中,可以声明一个静态的成员对象,但是此时仅仅声明,没有定义,也不会创建这个内部的静态成员对象.只有在类体外部定以后才能创建这个对象. #include<iostream> usin ...

  7. event对象的理解

    0.给对象绑定事件准确的说是给对象事件绑定事件函数 1.event:事件对象,当一个事件发生的时候,和当前这个对象发生的事件有关的信息都会被i临时保存到event对象中 2.event对象必须在一个事 ...

  8. swiper3d横向滚动多张炫酷切换banner

    最近有了个新需求,swiper3d横向滚动多张炫酷切换banner要和elementUI里边走马灯的卡片化card 类似,但是还需要h5手机触摸滚动啊啊啊啊,昨天折腾了半个早上总算完成,今天乖乖跑来m ...

  9. 2018.08.19 NOIP模拟 number(类数位dp)

    Number 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 如果一个数能够表示成两两不同的 3 的幂次的和,就说这个数是好的. 比如 13 是好的,因为 13 = 9 + 3 + ...

  10. 第四章 代词(Les pronoms )

    ★人称代词 .主语人称代词 第一人称和第二人称属纯人称代词,只能代人不能代物;第三人称可代人,亦可代物.如: La Terre est ronde. Elle tourne autour du Sol ...