一、Fragment的设计哲学

  Android在3.0中引入了fragments的概念,主要目的是用在大屏幕设备上——例如平板电脑上,支持更加动态和灵活的UI设计。平板电脑的屏幕比手机的大得多,有更多的空间来放更多的UI组件,并且这些组件之间会产生更多的交互。

  针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应平板神马超级大屏的。难道无法做到一个App可以同时适应手机和平板么,当然了,必须有啊。Fragment的出现就是为了解决这样的问题。你可以把Fragment当成Activity的一个界面的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成,更帅气的是Fragment拥有自己的生命周期和接收、处理用户的事件,这样就不必在Activity写一堆控件的事件处理的代码了。更为重要的是,你可以动态的添加、替换和移除某个Fragment。

  

下图是文档中给出的一个Fragment分别对应手机与平板间不同情况的处理图:

PS:简单的新闻浏览页面,使用两个Fragment分别显示新闻列表与新闻内容;

  Fragment在应用中应当是一个模块化和可重用的组件,因为Fragment定义了他自己的布局,以及通过使用他自己的生命周期回调方法定义了他自己的行为,可以将Fragment包含到多个Activity中。

二、静态加载Fragment

  Fragment知识概要:

    • Fragment 可以作为Activity界面的一部分组成出现(不能单独使用)
    • 可以在一个Activity中同时出现多个fragment,并且一个fragment也可以在多个activity中使用
    • 在activity运行过程中,可以添加、一处或替换fragment
    • fragment可以响应自己的输入事件,并且有自己的生命周期,他们的生命周期会受宿主activity的生命周期影响,比如Activity被destory销毁了,他也会跟着销毁

  

onCreateView()方法

  Fragment第一次绘制它的用户界面的时候,系统会调用此方法,未来绘制Fragment的UI,此方法必须返回一个View,如果不显示UI,返回NULL即可。

  在activity的layout文件中声明Fragment,需要特别注意的是<fragment>中的android: name 属性指定了在layout中实例化的Fragment类

  标识Fragment的方法:

    android:id 属性提供一个唯一的ID

    android:tag 属性提供一个唯一字符串

1、fragment布局文件,显示fragment显示内容控件

 <?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:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

fragment.xml

2、自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView()方法 在该方法中调用:inflater.inflate()方法加载Fragment的布局文件,接着返回加载的view对象

 package com.example.fragment;

 import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { //layout布局文件转换成view对象
/**
* resource:Fragment需要加载的布局文件
* root:加载layout的父ViewGroup
* attachToRoot:flase,不反回父ViewGroup
*/
View view = inflater.inflate(R.layout.fragment, container, false);
TextView text = (TextView) view.findViewById(R.id.text);
text.setText("加载静态Fragment");
return view ; }
}

MyFragment.java

3、在需要加载Fragment的Activity对应的布局文件中添加fragment的标签, 记住,name属性是全限定类名哦,就是要包含Fragment的包名

 <?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" > <fragment
android:id="@+id/fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="com.example.fragment.MyFragment"
/>
</LinearLayout>

main2.xml

4、 Activity在onCreate( )方法中调用setContentView()加载布局文件即可!(可添加事件)

 import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity2 extends Activity{ private TextView tv; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main2); Button button = (Button) findViewById(R.id.button);
tv = (TextView) findViewById(R.id.text);
button.setText("改变");
button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
tv.setText("TextView改变了");
}
});
}
}

MainActivity2.java

三、动态加载

  撰写代码将Fragmen添加到一个Activity layout 中

    add():添加一个Fragment(指定要添加的fragment 和 要插入的View)

    与此类似的还有remove() 、替换()

  处理Frament事务

  格局用户的交互情况,对Fragment进行添加、移除、替换,以及执行其他动作,提交给Activity的每一套变化被称作一个事务

  FragmentManager fragmentManager = getFragmentManager();

  FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

  每一个事务都是同时执行一套变化,可以在一个事务中设置所有想执行的变化,包括add()、remove()、replace()、然后提交给Activity,必须调用commit()方法

  如果允许用户通过按下back按键返回到前一个Fragment状态,调用commit()之前可以加入addToBackStack()方法

MyFragment2.xml

 package com.example.fragment;

 import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyFragment2 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { //layout布局文件转换成view对象
/**
* resource:Fragment需要加载的布局文件
* root:加载layout的父ViewGroup
* attachToRoot:flase,不反回父ViewGroup
*/
View view = inflater.inflate(R.layout.fragment, container, false);
TextView text = (TextView) view.findViewById(R.id.text);
text.setText("动态加载Fragment");
return view ; }
}

MyFragment2

主要代码

Fragment与activity通信

生命周期图:

  

探究fragment生命周期案例:

  

 package com.example.fragment;

 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.widget.Button; public class MainActivity3 extends Activity { private Button button;
private boolean flag = true; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main3);
init();
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction(); if (flag) {
MyFragment4 frag4=new MyFragment4();
beginTransaction.replace(R.id.layout, frag4);
flag=false;
} else {
MyFragment3 frag3=new MyFragment3();
beginTransaction.replace(R.id.layout, frag3);
flag=true; } beginTransaction.commit();
}
}); } private void init() {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
MyFragment3 frag3 = new MyFragment3();
beginTransaction.add(R.id.layout,frag3);
beginTransaction.commit();
} }

MainActivity3.java

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:text="切换Fragment"
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</Button> </LinearLayout>

main3.xml

 package com.example.fragment;

 import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyFragment3 extends Fragment { /**
* 每次创建都会绘制Fragment的View组件
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView tv = (TextView) view.findViewById(R.id.text);
tv.setText("第一个ragment");
Log.i("Main", "Fragment1---onCreateView()");
return view;
} /**
* 当fragment被添加Activity时候慧回调此方法,并且只调用一次
*/
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.i("Main", "Fragment1---onAttach()"); } /**
* 创建Fragment时回调
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Main", "Fragment1---onCreate()"); } /**
* 当Fragment所长的activity启动完成后调用
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("Main", "Fragment1---onActivityCreated()"); } /**
* 启动Fragment
*
*/
@Override
public void onStart() {
super.onStart();
Log.i("Main", "Fragment1---onStart()"); } /**
* 恢复Fragment时会被回调,调用onStart()方法后 一定调用onResume()方法
*/
@Override
public void onResume() {
super.onResume();
Log.i("Main", "Fragment1---onResume()"); } /**
* 暂停Fragment
*/
@Override
public void onPause() {
super.onPause();
Log.i("Main", "Fragment1---onPause()"); } /**
* 停止Fragment
*/
@Override
public void onStop() {
super.onStop();
Log.i("Main", "Fragment1---onStop()"); } /**
*销毁 Fragment所包含的View组件
*/
@Override
public void onDestroyView() {
super.onDestroyView();
Log.i("Main", "Fragment1---onDestroyView()"); } /**
* 销毁Fragment是被回调
*/
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Main", "Fragment1---onDestroy()"); } /**
* Fragment从Activity中删除时会回调该方法,只会调用一次
*/
@Override
public void onDetach() {
super.onDetach();
Log.i("Main", "Fragment1---onDetach()");
}
}

MyFragment3.java

MyFragment4.java

  

测试顺序:启动fragment—>回到桌面—>回到应用—>切换fragment—>退出fragment

日志打印:

    

    

  总结:

  1)启动fragment

  onAttach()—>onCreat()—>onCreateView()—>onActivityCreated()—>onStart()—>onResume()

  2)锁屏

  onPause()—>onStop()

  3)解锁

  onStart()—>onResume()

  4)切换到其他的Fragment

  第一个:onPause()—>onStop()—>onDestroyView()—>onDestroy()—>onDetach

  第二个:onAttach()—>onCreat()—>onCreateView()—>onActivityCreated()—>onStart()—>onResume()

Fragment 与Activity通信

  1)Fragment可调用getActivity()方法获取它所在的Activity

  2)Activity可调用FragmentManager的findFragmentById()或findFragmentByTag()方法获取Fragment

Activity——>Fragment:在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法

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

更详细也可以参考:http://www.itnose.net/detail/6396730.html

android之Fragment基础详解(一)的更多相关文章

  1. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  2. Android Fragment用法详解(2)--动态添加Fragment

    在上一篇文章<Android Fragment用法详解(1)--静态使用Fragment>我们讲解了Fragment的最简单的用法.这次我们来说一说Fragment复杂一丢丢的用法.在代码 ...

  3. 《Android NFC 开发实战详解 》简介+源码+样章+勘误ING

    <Android NFC 开发实战详解>简介+源码+样章+勘误ING SkySeraph Mar. 14th  2014 Email:skyseraph00@163.com 更多精彩请直接 ...

  4. 给 Android 开发者的 RxJava 详解

    我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 .而最近这几个 ...

  5. Android屏幕适配问题详解

    上篇-Android本地化资源目录详解 :http://www.cnblogs.com/steffen/p/3833048.html 单位: px(像素):屏幕上的点. in(英寸):长度单位. mm ...

  6. android ------- 开发者的 RxJava 详解

    在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://github. ...

  7. Android JNI作用及其详解

    Android JNI作用及其详解 Java Native Interface (JNI)标准是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 J ...

  8. 转:android Support 兼容包详解

    本文转自stormzhang的ANDROID SUPPORT兼容包详解 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清 ...

  9. android:TableLayout表格布局详解

    http://blog.csdn.net/justoneroad/article/details/6835915 这篇博文包括的内容:1.TableLayout简介2.TableLayout行列数的确 ...

随机推荐

  1. eclipse下的webservice开发

    关于eclipse下的webservice开发,有非常多的教程,这里只记下学习过程中的弯路: 1.无论是CXF模式还是AXIS模式,在出现start server之后,点击next报错:"s ...

  2. ASP.NET 生命周期 简介

    当我们在浏览器地址栏中输入网址,回车查看页面时,这时会向服务器端(IIS)发送一个request请求,服务器就会判断发送过来的请求页面,  完全识别 HTTP 页面处理程序类后,ASP.NET 运行时 ...

  3. Modelsim-altera 仿真 顶层原理图的解决办法

    解决办法:首先需要将.bdf原理图文件转换为Verilog HDL等第三方EDA工具所支持的标准描述文件.在Quartus下,保持*.bdf为活动窗口状态,运行[File]/[Create/Updat ...

  4. 剑指Offer:解决难题时的三大方法

    1.画图 让抽象的东西变得直观生动起来.比如设计二叉树,链表,栈,队列这些数据结构时. 2.举例子 同样可以化抽象为直观.能够更清晰的展现思路.从例子归纳出一般做法. 3.分解 有时问题本身是比较复杂 ...

  5. 2.1 ARM家族大检阅

    芯片名称 ARM核 指令架构 S3C2440 ARM9 ARMv4T S3C6410 ARM11 ARMv6 S5PV210 Cortex A8 ARMv7-A Cortex M工控 Cortex R ...

  6. 微信小程序--摸索之旅

    首先 奉上腾讯官方文档 方便参考:https://mp.weixin.qq.com/debug/wxadoc/design/index.html  个人认为没说啥特别有用的信息(可能是我看的太粗糙了) ...

  7. Linux手动释放内存

    手动释放内存 1.sync将内存中的缓存写入磁盘 2.  to free pagecache, use echo 1 > /proc/sys/vm/drop_caches;       to f ...

  8. Android 调用系统联系人界面的添加联系人,添加已有联系人,编辑和修改。

    一.添加联系人 Intent addIntent = new Intent(Intent.ACTION_INSERT,Uri.withAppendedPath(Uri.parse("cont ...

  9. 在win7下将CapsLock按键变成esc

    我喜欢用vim来编辑,经常要按到esc,但是去按那个按键确实比较的远,而且CapsLock这个按键对我来说着实有些鸡肋,所以就想在win7上也能像ubuntu那样把capslock映射为esc,在网上 ...

  10. 主机WIFI网络环境下,Linux虚拟机网络设置

    在主机使用WIFI网络环境下,怎么样进行虚拟机静态ip设置和连接互联网呢,原理什么太麻烦,另类的网络共享而已: 1.其实简单将网络连接模式设置成NAT模式即可. 2.虚拟网络编辑器依旧是桥接模式,选择 ...