Fragment进阶
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的理解可以参考这篇博文:http://www.cnblogs.com/hibraincol/archive/2012/03/06/2382120.html
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 @Override 22 public boolean onCreateOptionsMenu(Menu menu) { 23 getMenuInflater().inflate(R.menu.main, menu); 24 return true; 25 } 26 27 @Override 28 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 @Override 45 protected void onStart() { 46 super.onStart(); 47 System.out.println("MainActivity--->>onStart()"); 48 //在MainActivity,oncreate()后,两个fragment还需要调用自己onCreatView 49 content = (TextView) findViewById(R.id.content); 50 } 51 52 @Override 53 protected void onResume() { 54 super.onResume(); 55 System.out.println("MainActivity--->>onResume()"); 56 } 57 58 }
Mainactivity对应的XML文件activity_main.xml:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity" > 7 8 <LinearLayout 9 android:id="@+id/Top" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:orientation="horizontal" /> 13 14 <LinearLayout 15 android:id="@+id/ActivityContent" 16 android:layout_width="match_parent" 17 android:layout_height="match_parent" 18 android:orientation="vertical" /> 19 20 </LinearLayout>
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 @Override 19 public void onAttach(Activity activity) { 20 super.onAttach(activity); 21 System.out.println("TopFragment--->>onAttach()"); 22 interact = (interactiveActivity) activity; 23 } 24 25 @Override 26 public void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 System.out.println("TopFragment--->>onCreate()"); 29 } 30 31 @Override 32 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 @Override 42 public void onStart() { 43 super.onStart(); 44 System.out.println("TopFragment--->>onStart"); 45 /* 46 * getActivity:Return the Activity this fragment is currently associated 47 * with getActivity()就是返回对应XML的Activity 48 */ 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 @Override 59 public void onResume() { 60 super.onResume(); 61 System.out.println("TopFragment--->>onResume"); 62 63 } 64 65 // 按钮的点击监听 66 @Override 67 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:
<?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="horizontal" > <Button android:id="@+id/one" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="第一页" /> <Button android:id="@+id/two" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="第二页" /> <Button android:id="@+id/three" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="第三页" /> </LinearLayout>
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 @Override 13 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 @Override 23 public void onStart() { 24 super.onStart(); 25 System.out.println("ContentFragment----->>onStart()"); 26 } 27 28 @Override 29 public void onResume() { 30 31 super.onResume(); 32 System.out.println("ContentFragment----->>onResume()"); 33 } 34 35 }
ContentFragment所引用的xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center" 6 android:orientation="vertical" > 7 8 <TextView 9 android:id="@+id/content" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:gravity="center" 13 android:text="内容页" /> 14 15 </LinearLayout>
运行后的效果:
点击按钮显示对应的页数.
在看看打印出来数据:可以了解到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的控件进行实例化