Fragment碎片

Fragment 简介

俗称“碎片”,Android是在Android 3.0 (API level 11)开始引入Fragment的。
Fragment名为碎片不过却和Activity十分相似,Fragment用来描述一些行为或一部分用户界面在一个Activity中,你可以合并多个fragment在一个单独的activity中建立多个UI面板,同时重用fragment在多个activity中.你可以认为fragment作为一个activity中的一节模块 ,fragment有自己的生命周期,接收自己的输入事件,你可以添加或移除从运行中的activity.
一个fragment必须总是嵌入在一个activity中,同时fragment的生命周期受activity而影响,举个例子吧,当activity 暂停,那么所有在这个activity的fragments将被destroy释放。然而当一个activity在运行比如resume时,你可以单独的操控每个fragment,比如添加或删除。

Fragment的两个包app包中的fragment和v4包中的fragment的使用的区别

1,app包中的fragment,因为这个是在3.0之后才有的,支持的版本太高,在低版本中是是用不了的
android.support.v4.app.Fragment:可以兼容到1.6的版本。
2,关于这两个fragment使用标签的问题:
app.fragment和v4.fragment都是可以使用<fragment>标签的,在布局中没什么区别
当v4.fragment使用标签的时候就要特别注意了:
当这个Activity要使用android.support.v4.app.Fragment的时候,这个Activity必须继承FragmentActivity,否则就会报错
Caused by: java.lang.ClassCastException: com.example.android_fragment_bottom.fragments.TopBarFragment cannot be cast to android.app.Fragment
此时如果不继承FragmentActivity的话,编译系统会把android.support.v4.app.Fragment当成app包中的Fragment来处理。但是此时我们导入的是v4包中的Fragment。
3,得到FragmentManager的方法不一样
android.app.Fragment:使用getFragmentManager()方法
android.support.v4.app.Fragment:使用getSupportFragmentManager()方法

Fragment优点:

1,Fragment可以使你能够将activity分离成多个可重用的组件,每个都有它自己的生命周期和UI。
2,Fragment可以轻松得创建动态灵活的UI设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
3,Fragment是一个独立的模块,紧紧地与activity绑定在一起。可以运行中动态地移除、加入、交换等。
4,Fragment提供一个新的方式让你在不同的安卓设备上统一你的UI。
5,Fragment 解决Activity间的切换不流畅,轻量切换。
6,Fragment 替代TabActivity做导航,性能更好。
7,Fragment 在4.2.版本中新增嵌套fragmeng使用方法,能够生成更好的界面效果。
8,Fragment做局部内容更新更方便,原来为了到达这一点要把多个布局放到一个activity里面,现在可以用多Fragment来代替,只有在需要的时候才加载Fragment,提高性能

Fragment 的生命周期:

先上一张Andorid API上关于Fragment的生命周期图:

对比图:
image.png

Fragment 图

image

生命周期的经历

  1. 当一个fragment被创建的时候,它会经历以下状态.
    onAttach()
    onCreate()
    onCreateView()
    onActivityCreated()
  2. 当这个fragment对用户可见的时候,它会经历以下状态。
    onStart()
    onResume()
  3. 当这个fragment进入“后台模式”的时候,它会经历以下状态。
    onPause()
    onStop()
  4. 当这个fragment被销毁了(或者持有它的activity被销毁了),它会经历以下状态。
    onPause()
    onStop()
    onDestroyView()
    onDestroy()
    onDetach()

下面对Fragment的每个生命周期方法以及与Activity的关联进行详细介绍:

1、onAttach()

这个时候 activity已经传进来了, 获得activity的传递的值 就可以进行 与activity的通信里, 当然也可以使用getActivity(),前提是这个fragment已经和宿主的activity关联,并且没有脱离,他只调用一次。注他还可以通过Activity参数强转成上下文

2、onCreate()

系统创建fragment的时候回调。

3、onCreateView()

第一次使用的时候 fragment会在这上面画一个layout出来, 要返回一个 布局的view,也可以返回null。尽量在这里不要做耗时操作,比如从数据库加载大量数据显示listview等。

4、onActivityCreated()

当Activity中的onCreate方法执行完后调用。

当执行onActivityCreated()的时候 activity的onCreate才刚完成,所以在onActivityCreated()调用之前 activity的onCreate可能还没有完成,所以不能在onCreateView()中进行与activity有交互的UI操作,UI交互操作可以在onActivityCreated()里面进行。

5、onStart()

Fragment 启动时回调,此时Fragment可见。

6、onResume()

获取焦点时回调。

7、onPause()

失去焦点时回调。

8、onStop()

Fragment不可见时回调。

9、onDestroyView()

Fragment中的布局被移除时调用。表示fragemnt销毁相关联的UI布局, 清除所有跟视图相关的资源。

10、onDestroy()

Fragment销毁时回调。

11、onDetach()

Fragment与Activity解除关联时回调。

activity和fragment同时运行时候的生命周期

oncreate

onAttach_Fragment

onCreate_Fragment

onCreateView_Fragment

onActivityCreated_Fragment

onStart

onStart_Fragment

onResume

onResume_Fragment

按下home按键

onPause_Fragment

onPause

onStop_Fragment

onStop

切换回前台

onRestart

onStart

onStart_Fragment

onResume

onResume_Fragment

销毁activity

onPause_Fragment

onPause

onStop_Fragment

onStop

onDestroyView_Fragment

onDestroy_Fragment

onDetach_Fragment

onDestroy

android.app.Fragment包下的

Fragment 的使用

1种是在布局中调用碎片id,width,height,name.通过name指定一个继承了Fragment的类
2种在代码中碎片替换布局,写一个碎片类(要继承Fragment),碎片类加载布局通过inflater.inflate方式加载布局然后return出他的返回值.
布局代码中:

package com.example.fragment_text1;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {

    private FragmentManager manager;
    private Fragment_mymain mymain;
    private Fragment_go fragment_go;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getFragmentManager();// 获取碎片管理者
        mymain = new Fragment_mymain();// 首页
        fragment_go = new Fragment_go();// 购物
        // 一开始就是首页
        open();
    }

    private void open() {
//链式调用
manager.beginTransaction().replace(R.id.layout_fragment, mymain).commit();
            

    }

    public void dian(View v) {
        open();
    }

    public void wo(View v) {
        // 开启事务2
        FragmentTransaction beginTransaction = manager.beginTransaction();
        // 替换布局
        // 1,参数是要替换的布局
        // 2,参数是碎片类
        beginTransaction.replace(R.id.layout_fragment, fragment_go);
        // 提交事务
        beginTransaction.commit();

    }

    public void ya(View v) {

    }
}

主布局中.xml写了一个要被替换的布局

<FrameLayout
        android:id="@+id/layout_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#999">
    </FrameLayout>

首页碎片布局类,里面加载了布局,要继承碎片哦

package com.example.fragment_text1;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment_mymain extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View inflate = inflater.inflate(R.layout.layout_fragment, null);
    return inflate;
}
}

购物碎片布局类,里面加载了布局,,要继承碎片哦

package com.example.fragment_text1;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment_go extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View inflate = inflater.inflate(R.layout.fragment_go, null);
    return inflate;
}
}

效果图可以完成一个切换效果

image.png

android.support.v4.app.包下的Fragment 的使用

主活动页面要继承FragmentActivity才能用getSupportFragmentManager支持碎片管理器,向里面添加或替换的碎片类都继承import android.support.v4.app.Fragment;包下的Fragment
其他的添加和切换的方式和上面的一样,有点就是支持版本1.6

Fragment 的使用2

使用add,和show,hide可以保留痕迹:因他是添加而不是上面的替换
在oncreter里面我写了

        manager = getFragmentManager();//获取碎片管理器
        mymain = new Fragment_mymain();// 首页
        fragment_go = new Fragment_go();// 购物
        transaction = manager.beginTransaction();//开启服务
        transaction.add(R.id.hehe, mymain);//添加碎片,同样的注碎片只能添加一次
        transaction.add(R.id.hehe, fragment_go);
        transaction.commit();//开启一次服务就要提交一次

然后在点击事件中写

transaction = manager.beginTransaction();//开启
    transaction.show(mymain);//显示碎片
    transaction.hide(fragment_go);//隐藏碎片
transaction.commit();//提交

关于xml布局中Fragment与 FrameLayout的理解(动态替换的Fragment,为什么替换的布局是FrameLayout?)?

FrameLayout与Fragment标签都是用来放Fragment的,区别是,Fragment标签只能设置固定的Fragment,而FrameLayout中可以通过FragmentManager更换Fragment
注他A布局被替换之后他的属性和方法会在B替换碎片布局的身上

用fragment 替换 布局中的LinearLayout,然后如何换回来???

可以用.remove() 从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。

两个Fragment之间如何传递数据?

访问:http://www.cnblogs.com/graphics/p/5151547.html

默认开始碎片布局是最后添加的布局

Fragment add replace 区别?

用法上add配合hide或是remove使用,replace一般单独出现。
注:mymain进行了操作切换他自己时mymain里面的数据不会被干掉(因为我在oncreate中new了一次)
当切换成其他碎片的时候就会把mymain给干掉换成fragment_go

如何隔类add show hide remove

就要给add方法添加第三个参数是tag
show 和 hide ,remove 通过管理者.findFragmentTag("来制定碎片")

1、activity--->碎片
(1)如果碎片是通过xml文件生成的
    直接通过findViewById获取到碎片中的控件,然后给控件设置内容。
(2)如果碎片是通过代码生成的
     activity中添加碎片的时候,通过碎片对象的.setArgments(bundle)
     在fragment里面,通过getArgments()得到一个bundle对象,再从bundle对象里面获取内容

 2、碎片--->activity
     在activity中声明一个公共的方法,在这个方法中必须要有一个参数(参数类型就是要传递的数据类型)
     在fragment里面,通过getActivity(),可以获取到宿主activity对象,再调用宿主对象中提供的公共方法,
             把数据传递在这个方法中。

     获取assets目录中的文件流的方法:getActivity().getAssets().open("day10.txt");

 3、碎片--->碎片        
        先把一个碎片里的值传到它的宿主activity,再从宿主activity传到另一个碎片。
 注意:
        如果碎片中有按钮,那么按钮的点击事件只能用监听器的方式绑定,不能用属性onClick

碎片传递数据

发送
// 在Fragment1中创建Fragment2的实例
Fragment2  fragment2 = new Fragment2();
Bundle bundle = new Bundle();
// 传递实体类,需要实体类实现Serializable接口
bundle.putSerializable("key_entity", value_Entity);
// 传递字符串
bundle.putString("key_str",value_str);
// 传递int类型数
bundle.putInt("key_int",value_int);
//设置数据
fragment2.setArgument(bundle);
//调用上面的方法由 fragment1 跳转到 fragment2
showFragment(Fragment1.this, fragment2);

获取
// 获取由碎片1传递过来的实体类数据
Value_Entity value_Entity = (Value_Entity)getArgument.getSerializable("key_entity");
// 获取由碎片1传递过来的String类型数据
String value_str = (String)getArgument.getString("key_str");
// 获取由碎片1传递过来的int类型数据
int value_int = (String)getArgument.getInt("key_int");
}

View inflate = inflater.inflate(R.layout.fragment_xiaoxi, container, false);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容