Fragment的生命周期
onAttach();//当fragment被添加到activity中时会回调这个方法;只会调用一次
onCreate();//在fragment创建的时候回调这个方法;只会调用一次
onCreateView();//每次创建都会绘制Fragment的View组件时调用该方法,相当于fragment绑定一个布局,布局文件转换成view返回回来;
onActivityCreated();//fragment所在的activity启动完成后调用;
onStart();//启动Fragment时会被回调,
onResume();//方法,调用onStart()方法后面一定会调用这个方法,恢复fragment时回调
onPause();//暂停Fragment
onStop();//停止Fragment
onDestroyView();//销毁Fragment所包含的View组件,与onCreateView相对应
onDestroy();//销毁Fragment时会被回调
onDetach(); //Fragment从Activity中删除时回调这个方法,并且只调用一次
具体的操作对方法的调用:↓↓↓↓↓
启动fragment流程
onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()
屏幕锁屏
onPause()->onStop()
屏幕解锁
onStart()->onResume()
第一个fragment切换到第二个fragment
第一个:onPause()->onStop()->onDestoryView()->onDestory()->onDetach();
第二个:onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()
Destroyed【onDestroyView()->onDestroy()->onDetach()】
onDestroyView()方法:销毁Fragment所包含的View组件时回调
onDestroy()方法:销毁Fragment时会被回调
onDetach()方法:Fragment从Activity中删除时会被回调,且只调用一次
传值通信
activity向fragment传递数据有两种方式:
1、动态加载时,在加载fragment对象时通过Fragment.setArguments(bundle)的方式设置参数,然后开启事务加载fragment。此时就可以传递数据。
2、静态加载,在加载的fragment中设置几个自定义的方法可以给内部属性赋值的方法(就是普通的set方法),activity通过调用这个方法向fragment传递数据
传值通信:具体实现方法
第一步 先定义main4.xml布局文件
第二步 MainActivity4中加载main4.xml (setContentView(R.layout.main4))
第三步 建立新的MyFragment5类去接收Activity4传递过来的信息,并加载所对应的布局文件
第四步 在android_manifest中声明MainActivity4
第五步 按钮加跳转
第六步 MainActivity4的onClick中初始化MyFragment5
第七步 获取Fragment管理者并开启事物
第八步 把Fragment5添加进来(beginTransaction)
第九步 在MyFragment5 获取数据包 getArguments
Fragment与Activity通信
(1)Fragment可调用 getActivity() 方法获取它所在的Activity
(2)Activity可调用 FragmentMangaer 的 findFragmentById() 或 findFragmentByTag() 方法获取 Fratment
Activity->Fragment:在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法。
Fragment->Activit:需要在 Fragment 中定义一个内部回调接口,在让包含该Fragment的Activity实现该回调接口。这样Fragment可调用改回调方法将数据传递给Activity。
在Activity中使用setAraguments方法
Bundle bundle = new Bundle();
bundle.putString(key,value);
fragment.setArgumemts(bundle);
Fragment中 getArguments().get(key);
PS: activity向fragment传递参数,需要用到bundle对象来保存数据。
Fragment和Activity的通信(动态)的步骤
1. Fragment通过 getActivity() 来获得它所在的Activity
2. Activity->Fragment:
在Activity中创建Bundle数据包,并调用Fragment的 setArguments(Bundle bundle) 方法将数据包传递进去;
在Fragment中调用 getArguments() 获取数据包
3. Acitivty中:
MyFragment5 myFragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", message); //"name"为对应的key,message是传递的string
myFragment5.setArguments(bundle); //发送数据给myFragment5
对应的MyFragment5中:
Bundle bundle = getArguments(); //获取bundle数据包
String message = bundle.getString("name")+""; //把“name”key对应的value拿出来
mTV.setText(message);
4.Fragment->Activity:
需要在Fragment中定义一个内部回调接口,再让包含它的Activity实现该回调接口。这样Fragment中可调用该回调方法将数据传递给Activity。
(1)Fragment中定义一个内部回调接口
public interface MyListener {
public void response(String reponseString);
}
(2)Activity中实现该方法
MainActivity4 implements MyListener {
public void response(String reponseString) {
mTV.setText(reponseString);
}
}
(3)Fragment中回调MainActivity4中的该方法
((MyListener) getActivity()).response(responseString);
AND
Fragment作为被Activity加载的被动一方,要想实现向Activity传值通信,要解决以下几个问题:
1.Fragment要知道是哪个Activity加载了它(fragment需要有明确的标识:id或者name)
通过 onAttach() 方法可以让Fragment获取Activity的信息
2.在Fragment中创建一个Activity的对象,通过这个对象去调用Activity中的方法
3.Activity中的这个方法要满足如下条件:
Fragment与Activity的通信需要注意的3点:
(1) Activity传值给Fragment通过Bundle
(2) Fragment传值给Activity通过在Fragment中定义接口,实现 Attach(Activity activity) ,在Activity中实现该接口
(3) 除以上方法之外,还能通过静态传值,静态传值在Fragment中定义Get,Set方法。
进阶篇
怎么实现Fragment向Activity回传数据
- 1.想知道Fragment中获取加载了这个Fragment的Activity信息,即要知道是哪个Activity加载了Fragment–>onAttach()方法。在Activity加载Fragment的时候会回调这个方法,并且只调用一次,一旦Activity加载了Fragment,就会调onAttach()方法,其传入的参数就是Activity
- 2.在Fragment中实例化一个Activity对象,调用Activity中的某个方法,并且把要回传的数据作为这个方法的参数传递进去。实例化并不难做到,我们可以根据onAttach()方法传回来的参数activity直接创建一个Activity的对象出来,可是如果这样操作,就会把代码写死了,那如果有别的Activity来加载这个Fragment怎么办?怎么才能实现代码的重用和灵活性呢?–>继承和多态
- 3.前面我们说到需要Activity中有某个方法,可以让我们把要回传的数据作为参数传递进去,调用这个方法,这个方法会将Fragment传递的数据以某种方式展示给Activity,从而让Activity知道Fragment传了数据给它,但是我们怎么能够知道Activity中有什么方法呢,又怎么能够确保Activity中有我们所需要的这种方法呢?
- 4.利用接口,是的,如果我们在Fragment中定义一个内部接口,然后让需要加这个Fragment的Activity实现这个接口,我们就可以解决上面的问题。首先,接口中定义一个我们需要的方法,Activity实现了接口,就必须要提供这个方法,这样我们就可以知道我们要调用哪个方法去实现传送数据,并且我们可以知道Activity中一定有这个方法
- 5.那么既然Activity实现了Fragment的内部接口,那么Activity就可以看作是这个接口的一个子类,那么也就是Fragment的一个子类,我们在Fragment中实例化Activity对象的时候就可以采用父类对象指向子类引用的方式。这样的好处是,当我们在onAttach()方法中去实例化一个Activity对象时,就能实现代码的重用和灵活性,哪个Activity加载了Fragment,Fragment中就实例化哪个Activity的对象