fragment之间的通信,fragment和Activity生命周期之间的关系
通过上一篇浅显的学习了一下,怎么在Activity中添加fragment。在介绍fragment之间的通信之前,我们来回顾一些fragment的生命周期:
Activity的生命周期会影响fragment的生命周期的,针对Activity的每一个生命周期的回调都会有一个类似的针对Fragment的回调,当Activity收到onPause()回调时,在Activity中每个Fragment都会收到onPause()回调。
看到fragment的生命周期是不是有种似成相识感觉,对,它和Activity的生命周期很像。对一些常用的生命周期函数做个说明:
onAttach()
当Fragment已经跟Activity关联上的时候,这个回调被调用。Activity会作为onAttach()回调方法的参数来传递。
onCreateView()
创建跟Fragment关联的视图层时,调用这个回调方法。
onActivityCreated()
当Activity的onCreate()方法执行完之后,调用这个回调方法。
onDestroyView()
当跟Fragment关联的视图层正在被删除时,调用这个回调方法。
onDetach()
当从Activity中解除Fragment的关联时,调用这个回调方法。
对于activity的理解可以参考这篇博文:
Activity和fragment有个很大的区别是:
Activity在onPause()后会自己进入到周期Stack当中, 而fragment需要调用addToBackStack()方法后才能回到backStack当中去,然后再一次启动
下面就通过一个例子来说明fragment之间怎么通信的和fragment与activity之间的一些关系:
Mainactivity:
1 public class MainActivity extends FragmentActivity implements 2 interactiveActivity { // 别忘了要继承接口 3 4 private TextView content = null; // ContentFragment中的TextView 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main);10 System.out.println("MainActivity--->>onCreat()开始");11 ContentFragment contentfragment = new ContentFragment();12 TopFragment topfragment = new TopFragment();13 FragmentManager fm = getSupportFragmentManager();14 FragmentTransaction ft = fm.beginTransaction();15 ft.add(R.id.ActivityContent, contentfragment);16 ft.add(R.id.Top, topfragment);17 ft.commit();18 System.out.println("MainActivity--->>onCreat()结束");19 }20 21 @Override22 public boolean onCreateOptionsMenu(Menu menu) {23 getMenuInflater().inflate(R.menu.main, menu);24 return true;25 }26 27 @Override28 public void showContent(int i) {29 switch (i) {30 case 1:31 content.setText("第一页");32 break;33 case 2:34 content.setText("第二页");35 break;36 case 3:37 content.setText("第三页");38 break;39 default:40 break;41 }42 }43 44 @Override45 protected void onStart() {46 super.onStart();47 System.out.println("MainActivity--->>onStart()");48 //在MainActivity,oncreate()后,两个fragment还需要调用自己onCreatView49 content = (TextView) findViewById(R.id.content);50 }51 52 @Override53 protected void onResume() {54 super.onResume();55 System.out.println("MainActivity--->>onResume()");56 }57 58 }
Mainactivity对应的XML文件activity_main.xml:
17 8 13 14 19 20
TopFragment的class
1 public class TopFragment extends Fragment implements OnClickListener { 2 3 public TopFragment() { 4 } 5 6 private interactiveActivity interact; 7 private Button btn1; 8 private Button btn2; 9 private Button btn3;10 11 // 创建一个接口用于与activity之间进行交互12 public interface interactiveActivity {13 // 根据i的不同,对content 内容进行修改14 public void showContent(int i);15 }16 17 /** Fragment第一次附属于Activity时调用,在onCreate之前调用 */18 @Override19 public void onAttach(Activity activity) {20 super.onAttach(activity);21 System.out.println("TopFragment--->>onAttach()");22 interact = (interactiveActivity) activity;23 }24 25 @Override26 public void onCreate(Bundle savedInstanceState) {27 super.onCreate(savedInstanceState);28 System.out.println("TopFragment--->>onCreate()");29 }30 31 @Override32 public View onCreateView(LayoutInflater inflater, ViewGroup container,33 Bundle savedInstanceState) {34 35 System.out.println("TopFragment--->>onCreateView()");36 // 在获取了xml后对其中的控件进行实例化37 return inflater.inflate(R.layout.top_fragment, container, false);38 39 }40 41 @Override42 public void onStart() {43 super.onStart();44 System.out.println("TopFragment--->>onStart");45 /*46 * getActivity:Return the Activity this fragment is currently associated47 * with getActivity()就是返回对应XML的Activity48 */49 btn1 = (Button) getActivity().findViewById(R.id.one);50 btn2 = (Button) getActivity().findViewById(R.id.two);51 btn3 = (Button) getActivity().findViewById(R.id.three);52 btn1.setOnClickListener(this);53 btn2.setOnClickListener(this);54 btn3.setOnClickListener(this);55 56 }57 58 @Override59 public void onResume() {60 super.onResume();61 System.out.println("TopFragment--->>onResume");62 63 }64 65 // 按钮的点击监听66 @Override67 public void onClick(View v) {68 switch (v.getId()) {69 case R.id.one:70 interact.showContent(1);71 break;72 case R.id.two:73 interact.showContent(2);74 break;75 case R.id.three:76 interact.showContent(3);77 break;78 default:79 break;80 81 }82 }83 84 }
TopFragment所引用的top_fragment.xml:
ContentFragment的class:
1 public class ContentFragment extends Fragment { 2 3 public ContentFragment() { 4 } 5 6 @Override 7 public void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 System.out.println("ContentFragment----->>onCreat()");10 }11 12 @Override13 public View onCreateView(LayoutInflater inflater, ViewGroup container,14 Bundle savedInstanceState) {15 16 System.out.println("ContentFragment----->>onCreatView()");17 View view = (View) inflater.inflate(R.layout.content_fragment,18 container, false);19 return view;20 }21 22 @Override23 public void onStart() {24 super.onStart();25 System.out.println("ContentFragment----->>onStart()");26 }27 28 @Override29 public void onResume() {30 31 super.onResume();32 System.out.println("ContentFragment----->>onResume()");33 }34 35 }
ContentFragment所引用的xml:
1 27 8 14 15
运行后的效果:
点击按钮显示对应的页数.
在看看打印出来数据:可以了解到activity和fragment的生命周期是有先后顺序的。
Activity的onCreate()------>>fragment的Attach()---->>fragment的onCreate()------>>fragment的onCreateView()--->>(在多个fragment的onCreateView()执行完后,就又开始执行每个fragment的
onStart())----->>Activity的onStart() ----->>Activity的onResume() ------>>fragment的onResume()
因为在onCreate()当中不能获得fragment的中的控件,因为要等fragement执行了onCreateView()后才能获取,所以只能在onCreateView()后的Activity的生命函数当中才能对fragment的控件进行实例化