zoukankan      html  css  js  c++  java
  • 【转】 Pro Android学习笔记(三八):Fragment(3):基础小例子-续

    目录(?)[-]

    1. Step 2实现Fragment指定调用类TitleFragment
      1. onInflate和onAttach
      2. onCreate和onCreateView
      3. onActivityCreated
      4. onStartonResumeonPause和onStop
      5. onDestroyViewonDestroy和onDetach
      6. 与用户互动处理

    Step 2:实现Fragment指定调用类TitleFragment

    系统执行setContentView(R.layout.fragment_basic)调用时,左边fragment指定了实现类,则调用该类TitleFragment。我们结合生命周期来进行学习。Fragment的生命周期看起来比Activity要复杂,因为它要处理与activity之间的关系。

    onInflate()和onAttach()

    Fragment可有一个view hierarchy,以之与用户互动。这个view层级可以根据XML布局文件被创建(inflated)或通过代码创建。view层级需要与activity关联,才能被用户看见。Fragment的最初的两个生命周期为onInflate和onAttach。

    /* 左边fragment是list,和ListActivity一样,继承ListFragment */
    public class TitleFragment extends ListFragment{
        private FragmentBasicTest myActivity = null; 
        private int mCurCheckPosition = 0;  
         
        …... 略 …… 

        @Override //【2】在fragment与activity关联后调用onAttach()。由于右边fragment的具体实现在activity的showDetails()中实现,需要获取activity的对象。 当然也可以直接用getActivity()获取。
        public void onAttach(Activity activity) {  
            showInfo("onAttach() is called. activity is " + activity); 
            showInfo("   getActivity() : " + getActivity());

            super.onAttach(activity);
            myActivity = (FragmentBasicTest)activity; 
        }     

        @Override//【1】首先调用:在Activity调用setContentView()时,xml中有<fragment>时被调用。bundle存贮的是fragment的状态,并非初始化的值。一般而言,此时太早,还没有和activity关联,一般很少需要在此进行处理,除非我们需要处理fragment的属性或参数。在API的reference中,Fragment的主要lifecycle甚至没有将onInflate()列入,因此在实际编程中,会较少用到。
        public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) { 
            showInfo("onInfalte() is called");
            showInfo("   activity : " + activity);
            showInfo("   getActivity() : " + getActivity()); //Fragment尚为关联activity
            showInfo("   attribute是fragment的属相,例如R.id.titles =  " + R.id.titles); 
            for(int i = 0 ; i< attrs.getAttributeCount() ; i ++){ 
                showInfo("    attribute " + i + " :" + attrs.getAttributeName(i) + " = " + attrs.getAttributeValue(i));
            } 
            showInfo("   bundle : " + savedInstanceState);
           super.onInflate(activity, attrs, savedInstanceState);
        } 

        private void showInfo(String s){ 
            Log.d("TitleFragment",s); 
        }     
    }

    我们看看运行的logcat显示。我们可以看出,在activity调用setContentView时,先调用Flagment中的onflate(),然后调用onAttach()。在onInfalte()中可以读取到我们在xml文件中<fragment… >设置的属性。在后面实现右边的fragment中,由于布局文件中<fragment …>中并没有指定class属性,而是在代码中实现,故没有onInflate()状态。

    与activity的关联:看到onInfalte()和onAttach()都可以获得activity对象,但是如果采用getActivity()来获取,则发现onInfalte()的阶段对处理UI太早,都不能关联到activity。

    参数:在整个生命周期,可以通过getArguments()来获取参数,但是不能在与activity关联后进行setArgments(),只能在初始化极早的阶段,例如构造函数和onInflate()。

    onCreate()和onCreateView()

    @Override //【3】在创建fragment中进行初始化时调用。注意此处的bundle参数,是存储fragment的状态。如果我们要为fragment启动一个后台线程,可以考虑将代码放于此处。 
    public void onCreate(Bundle savedInstanceState) {  
       showInfo("onCreate() is called. ");
        super.onCreate(savedInstanceState);


    @Override //【4】创建fragment,并返回fragment的view层次结构,用于对UI的设计。本例继承了ListFragment实现,由其生成ListView,它的资源ID是android.R.id.list1,或者可以通过getListView()来获取。我们在此不需要在进行特别的处理,仅用于跟踪生命周期。
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        showInfo("onCreateView() is called. ");
        return super.onCreateView(inflater, container, savedInstanceState);

    onCreate()和onCreateView()都是在activity调用setContentView()时被调用。也就是activity上未完成onCreate(),因此不应该在此加入与activity的view相关的代码。而后面的生命周期这是在activity完成onCreate()之后调用的。

    onActivityCreated()

    onActivityCreated顾名思义,是在activity完成onCreate()后被调用。我们可以在此处理activity的其他UI操作,而其他的fragment已经与activity关联,我们可以进行相互间处理。这也是用户看到UI界面之前的最后一个状态,对于从saved状态中重新创建activity及fragment来讲是重要状态。

    回想一下,在ListActivity中是在setContentView()后面进行Adapter的设置,因为setContentView已经提供了view层级,因此在fragment中具体设置list也放在fragment的onCreateView()之后的生命周期onActivityCreated()中执行。

       @Override //【5】onActivityCreated()在activity完成onCreate()后执行,在此可以加入UI设计(onCreateView())之后,UI被用户看到之前的代码。 
        public void onActivityCreated(Bundle savedInstanceState) {  
            showInfo("onActivityCreated() is called.");
            super.onActivityCreated(savedInstanceState); 
           // 1)通过Adapter进行view和data的关联   
            setListAdapter
    (new ArrayAdapter<String>(getActivity(),   //注意:在ListFragment中要直接和ListView(通过id或者getListView()获取)关联,而要用setListAdapter()
                    android.R.layout.simple_list_item_1, 
                    BooksInfo.TITLES)); 
            ListView lv = getListView(); 
            lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
            lv.setSelection(mCurCheckPosition); 
            //2)根据书名设置右边framgent UI。 
            myActivity.showDetails(mCurCheckPosition); 
        }

    onStart()、onResume()、onPause()和onStop()

    这几个状态和activty的相应状体相似,对应为可视,可互动,不可互动和不可视。和activity的生命周期图相对比,从不可视的后台回复到可视的前台的过程是onStop()—>onRestart()—>onStart()。而fragment为onStop()—>onStart()。

    onDestroyView()、onDestroy和onDetach()

    当fragment允许与view相关的资源释放时调用onDestroyView(),清空通过onCreateView()所返回的view。接着,onDestroy()进行最后fragment状态的清空。最后调用onDetach(),删除与activity的关联()。

    与用户互动处理

    @Override //当用户点击书名,在右边fragment中显示相关的内容。在ListFragment中可以直接通过回调函数onListItemClick来实现。
    public void onListItemClick(ListView l, View v, int position, long id) { 
        mCurCheckPosition = position; 
        myActivity.showDetails(mCurCheckPosition); 

    本博文涉及的例子代码,可以在Pro Android学习:Fragment中下载。

    相关链接: 我的Android开发相关文章

  • 相关阅读:
    MSXML应用总结
    MsXml创建和解析XML示例
    解决IAR无法跳转的问题
    总结4
    1012
    1010
    acm学习总结
    1005
    1004
    1006
  • 原文地址:https://www.cnblogs.com/blongfree/p/5047975.html
Copyright © 2011-2022 走看看