动手理解Fragment
上个周末参加了某公司的面试,问到了Fragment生命周期的问题,深深地感觉自己被鄙视了。。。回家之后写了段代码研究了一下,可算是搞明白了,着实发现Google之所以要大力推进Fragment还是有原因的,果然很好用很便捷啊。
首先需要了解的是Fragment本身的生命周期,遂使用强大的logcat,写了这么一段代码:
1 package com.example.adapter; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.os.Bundle; 6 import android.support.v4.app.Fragment; 7 import android.util.Log; 8 import android.view.LayoutInflater; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.widget.ListView; 12 13 import com.example.data.AnalyzeJson; 14 import com.example.demoforhaici.R; 15 import com.example.model.Word; 16 17 public class FragmentPage2 extends Fragment 18 { 19 public final int ARG_SECTION_NUMBER =2; 20 21 private Word myWord; 22 23 public FragmentPage2() { 24 } 25 26 @Override 27 public View onCreateView(LayoutInflater inflater, ViewGroup container, 28 Bundle savedInstanceState) { 29 Log.e("OnCreateView", this.toString()); 30 View rootView = inflater.inflate(R.layout.fragment_page2, 31 container, false); 32 AnalyzeJson json = new AnalyzeJson(""); 33 myWord = json.GetTencentInfoByJson(); 34 Context context = getActivity(); 35 ListView fragment_page2_List = (ListView)rootView.findViewById(R.id.fragment_page2_List); 36 FragmentPage2_ListViewAdapter adapter = new FragmentPage2_ListViewAdapter(context, R.layout.vocabulary_item, 1024, myWord); 37 fragment_page2_List.setAdapter(adapter); 38 39 return rootView; 40 } 41 @Override 42 public void onActivityCreated(Bundle savedInstanceState) { 43 Log.e("OnActivityCreated", this.toString()); 44 super.onActivityCreated(savedInstanceState); 45 } 46 @Override 47 public void onAttach(Activity activity) { 48 Log.e("OnAttach", this.toString()); 49 super.onAttach(activity); 50 } 51 @Override 52 public void onDestroyView() { 53 Log.e("OnDestroyView", this.toString()); 54 super.onDestroyView(); 55 } 56 @Override 57 public void onCreate(Bundle savedInstanceState) { 58 Log.e("OnCreate", this.toString()); 59 super.onCreate(savedInstanceState); 60 } 61 @Override 62 public void onDestroy() { 63 Log.e("OnDestroy", this.toString()); 64 super.onDestroy(); 65 } 66 @Override 67 public void onDetach() { 68 Log.e("OnDetach", this.toString()); 69 super.onDetach(); 70 } 71 @Override 72 public void onPause() { 73 Log.e("OnPause", this.toString()); 74 super.onPause(); 75 } 76 @Override 77 public void onResume() { 78 Log.e("OnResume", this.toString()); 79 super.onResume(); 80 } 81 @Override 82 public void onStart() { 83 Log.e("OnStart", this.toString()); 84 super.onStart(); 85 } 86 @Override 87 public void onStop() { 88 Log.e("OnStop", this.toString()); 89 super.onStop(); 90 } 91 92 }
跟踪出的结果如下,嗯,果然还是和Activity很相似的。到达resume时,Fragment就处在活跃状态了。
但是,这还没完,我们在使用Fragment时通常会伴随着ViewPager,那么他们之间的关系又是怎么样的呢?
我在一个ViewPager使用了3个Fragment,它们中都有监听事件,当进入Activity时,我们可以发现已经有2个Fragment处在onResume状态,这种逻辑是合理的,因为只有当Fragment已经被绘制出来了之后,才能让用户在滑动屏幕时看到滑动的效果。
当滑动到第二个Fragment时,又多出了下面几条log,可以看到下一个Fragment也已经被创建并处在onResume状态,此时处在onResume状态的Fragment应该是3个。也就是说不论是向左还是向右滑动都可以直接看到相应的界面,这当然也是合理的。
当滑动到第三个Fragment时,我们可以看到第一个Fragment被停掉了,也就是说,只有和当前Fragment距离最近的两个或一个Fragment会处在onResume状态,目的就是用户在滑动屏幕时可以看到跟随手指滑动的效果,而距离较远的,需要destroy掉,以节省内存。
另外,由于只有三个Fragment,因此如果有四个或者更多的话,当滑动到第三个Fragment时可以看到的场景应该是第一个Fragment被Destroy,并且第四个Fragment被Resume。
源码链接:https://github.com/AtWinner/DemoForHaici
敬请拍砖