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. centos7.5配置双网卡上网

    一.环境及说明 当初有这个需求,主要是帮一个高校的客户搭建一个大数据集群,使用的是校园网,交换机上一个端口只能连接一部电脑上网,不能通过路由组建子网,确保集群中的服务器有子网ip的同时,也能够通过公网 ...

  2. IIS不能下载.apk文件

    IIS服务器不能下载.apk文件的原因:iis的默认MIME类型中没有.apk文件,所以无法下载. 打开IIS服务管理器,找到服务器,右键-属性,打开IIS服务属性: 单击MIME类型下的“MIME类 ...

  3. Problem B. Market(market.c/cpp/pas)

    Problem B. Market(market.c/cpp/pas)Time limit: 1 secondsMemory limit: 128 megabytes在比特镇一共有 n 家商店,编号依 ...

  4. c++ 中的符号与关键字

    符号按照符号的ASC码数值从小到达排列,关键字按照英文字母排序. & [38] 位运算:取地址:左值引用[指针.引用都是可以做类型转换的] #include <iostream> ...

  5. scrapy官方安装方法

    安装依赖 sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libss ...

  6. KbmMW 4.5 发布

    We are happy to announce the release of kbmMW v. 4.50.00 Professional, Enterprise and CodeGear Editi ...

  7. 2018.07.06 POJ 1459 Power Network(多源多汇最大流)

    Power Network Time Limit: 2000MS Memory Limit: 32768K Description A power network consists of nodes ...

  8. 使用async-http-client实现异步批量http请求

    最近项目中需要在微服务中调用rest接口,而且需要调用得次数很多,所以同步得http客户端已经不满足要求,在网上查阅资料后发现了async-http-client这个包得性能不错,所以写了个demo测 ...

  9. cmake-add_definitions

    add_definitions: Adds -D define flags to the compilation of source files. add_definitions(-DFOO -DBA ...

  10. python-optparse模块给脚本增加参数选项

    import optparse parser = optparse.OptionParser('[-] Usage %prog '+ '-H <RHOST[s]> -l [-p -F ]' ...