Fragments 詳細使用(附案例源碼)

 FrameAndroid3.0纔出來的一個控件,在過去咱們顯示的都彩Activity而後進行設計,而Frame出來是爲了使一個窗口裏面可以具備多個Activityhtml

經過下圖下分析,Frame能夠在窗口內嵌入多個fragments,接下來的會給出源碼來實現下面的功能, ,主要完成的任務是當你點擊左側的listView項,右邊的fragments內容是隨着你的更新而更新的。android


Frame生命週期

OnCreate:當你須要在建立frame時對一些組件進行相應的初始化,就能夠在這裏面寫。api

onCreateView當你須要繪製一個界面的時候就須要調用這個回調的方法來返回一個view對象,若是你不想使用任何的界面時能夠返回null,還有注意的一件事情是當你橫豎屏切換的時候會屢次回調這個方法。app

onPause():當用戶離開這個fragment的時候會回調這個方法,而離開並不表明這個應用的結束ide

DialogFragment:這個方法是用於繪製一個對話框,這個對話框採用棧的方法,當你結束後能夠返回前一個窗體。函數

ListFragment:這個相似listView,顯示一個列表,列表中的項能夠經過adapter(好比一個SimpleCursorAdapter)來指定列表的項內容,當你單擊的時候一樣跟ListView同樣會有一個onListItemClick()回調的函數,來進行單擊列表項時的操做。佈局

PreferenceFragment:這個fragment的做用相似於 PreferenceActivity顯示一個 Preference對象的層次結構的列表,就是用戶設置界面來理解就能夠了。this

增長界面:

一般Fragment的界面採用interface的方式來選擇一個以有的layout XML文件來設計界面,經過前面的知識咱們能夠了解到,Fragments有一個oncreateView()的回調方法來決定顯示的界面,那麼就能夠在裏面用infalter來選擇,並且返回一個View對象。spa

傳入 onCreateView() 的 container 參數是你的fragment layout將要插入的父ViewGroup(來自activitylayout)。savedInstanceState 參數是一個 Bundle,若是fragment是被恢復的,它提供關於fragment的以前的實例的數據。設計

inflate() 方法有3個參數:

  • 想要加載的layoutresource ID

  • 加載的layout的父ViewGroup
    傳入container是很重要的,目的是爲了讓系統接受所要加載的layout的根viewlayout參數,
    由它將掛靠的父view指定。

  • 布爾值指示在加載期間,展開的layout是否應當附着到ViewGroup (第二個參數)。
    (在這個例子中指定了false, 由於系統已經把展開的layout插入到container – 傳入true會在最後的layout中建立一個多餘的view group。)



     @Override     publicView onCreateView(LayoutInflater inflater,ViewGroup container,                              Bundle savedInstanceState){         // Inflate the layout for this fragment         return inflater.inflate(R.layout.example_fragment, container,false);     } }publicstaticclassExampleFragmentextendsFragment{

添加一個Fragmentactivity中:

咱們能夠把Fragment加入到一個ActivityLayout佈局文件中,須要注意的是name屬性的做用就是指定一個fragment Class到佈局文件中。

3種方法來爲一個fragment提供一個標識:

  • 爲 android:id 屬性提供一個惟一ID

  • 爲 android:tag 屬性提供一個惟一字符串。

  • 若是以上2個你都沒有提供,系統使用容器viewID



 <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="horizontal"     android:layout_width="match_parent"     android:layout_height="match_parent">     <fragmentandroid:name="com.example.news.ArticleListFragment"             android:id="@+id/list"             android:layout_weight="1"             android:layout_width="0dp"             android:layout_height="match_parent"/>     <fragmentandroid:name="com.example.news.ArticleReaderFragment"             android:id="@+id/viewer"             android:layout_weight="2"             android:layout_width="0dp"             android:layout_height="match_parent"/> </LinearLayout><?xml version="1.0" encoding="utf-8"?>

而且fragment能夠添加到viewgroup裏面。

 FragmentTransaction fragmentTransaction = fragmentManager.; 此時你就能夠彩Add方法來添加一個view來插入到viewgrou中了  fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();FragmentManager fragmentManager = getFragmentManager()beginTransaction()ExampleFragment fragment =newExampleFragment();

還有,當你添加完成後必定要調用commit()方法,這個方法的做用相似於Sqllite中的事務,只要你調用這個方法纔會提交你所作的操做。

下圖是不一樣時期會回調的函數

例子:

那麼咱們仍是採用官方的案例來說解吧,那麼最終完成的功能以下圖所示,左邊是標題列表,右邊是根據你的選擇來顯示相應的內容。

首先咱們須要設計一個layout

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="horizontal"     android:layout_width="match_parent"android:layout_height="match_parent">     <fragmentclass="com.example.android.apis.app.FragmentLayout$TitlesFragment"             android:id="@+id/titles"android:layout_weight="1"             android:layout_width="0px"android:layout_height="match_parent"/>     <FrameLayoutandroid:id="@+id/details"android:layout_weight="1"             android:layout_width="0px"android:layout_height="match_parent"             android:background="?android:attr/detailsElementBackground"/> </LinearLayout>

當完成XML的設計後咱們還須要在Activity中的oncreate應用這個局面文件

protectedvoid onCreate(Bundle savedInstanceState){     super.onCreate(savedInstanceState);     setContentView(R.layout.fragment_layout); } TitleFragment是繼承listFragment主要用於標題的顯示。 publicstaticclassTitlesFragmentextendsListFragment{     boolean mDualPane;     int mCurCheckPosition =0;     @Override  //下面的回調方法是用來設計你的簾布     publicvoid onActivityCreated(Bundle savedInstanceState){         super.onActivityCreated(savedInstanceState);         // 經過setListAdapter來進行綁定列表項,simple_list_item_activated_1是系統自定義的,採用的是text來顯示列表項。         setListAdapter(newArrayAdapter<String>(getActivity(),                 android.R.layout.simple_list_item_activated_1,Shakespeare.TITLES));         View detailsFrame = getActivity().findViewById(R.id.details);         mDualPane = detailsFrame !=null&& detailsFrame.getVisibility()==View.VISIBLE;         if(savedInstanceState !=null){             // 恢復你最後選擇的狀態。             mCurCheckPosition = savedInstanceState.getInt("curChoice",0);         }         if(mDualPane){             // In dual-pane mode, the list view highlights the selected item.             getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);             // Make sure our UI is in the correct state.             showDetails(mCurCheckPosition);         }     }     @Override     publicvoid onSaveInstanceState(Bundle outState){         super.onSaveInstanceState(outState);         outState.putInt("curChoice", mCurCheckPosition);     }     @Override //當你單擊列表項就會回調這個方法,其中position是你單擊項的下標,showDetails函數的做用是經過你傳送的標題項來進行內容的選擇。     publicvoid onListItemClick(ListView l,View v,int position,long id){         showDetails(position);     }     /**      * Helper function to show the details of a selected item, either by      * displaying a fragment in-place in the current UI, or starting a      * whole new activity in which it is displayed.      */     void showDetails(int index){         mCurCheckPosition = index;         if(mDualPane){             // We can display everything in-place with fragments, so update             // the list to highlight the selected item and show the data.             getListView().setItemChecked(index,true);             // Check what fragment is currently shown, replace if needed.             DetailsFragment details =(DetailsFragment)                     getFragmentManager().findFragmentById(R.id.details);             if(details ==null|| details.getShownIndex()!= index){                 //從新設計一張新的視圖來顯示你所選擇標題的正文內容。                 details =DetailsFragment.newInstance(index);                 // 執行一個事務來替代之前存在的fragment                                 FragmentTransaction ft = getFragmentManager().beginTransaction();                 ft.replace(R.id.details, details);                 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);                 ft.commit();             }         }else{             //不然用一個新的DetailsActivity的來進行顯示。             // the dialog fragment with selected text.             Intent intent =newIntent();             intent.setClass(getActivity(),DetailsActivity.class);             intent.putExtra("index", index);             startActivity(intent);         }     } } DetailsFragment類:經過TitlesFragment來顯示相應的正文。 publicstaticclassDetailsFragmentextendsFragment{     /**      * Create a new instance of DetailsFragment, initialized to      *經過傳送過來的Index來選擇相應的內容      */     publicstaticDetailsFragment newInstance(int index){         DetailsFragment f =newDetailsFragment();         // Supply index input as an argument.         Bundle args =newBundle();         args.putInt("index", index);         f.setArguments(args);         return f;     }     publicint getShownIndex(){         return getArguments().getInt("index",0);     }     @Override     publicView onCreateView(LayoutInflater inflater,ViewGroup container,             Bundle savedInstanceState){         if(container ==null){             // We have different layouts, and in one of them this             // fragment's containing frame doesn't exist.  The fragment             // may still be created from its saved state, but there is             // no reason to try to create its view hierarchy because it             // won't be displayed.  Note this is not needed -- we could             // just run the code below, where we would create and return             // the view hierarchy; it would just never be used.             returnnull;         }         ScrollView scroller =newScrollView(getActivity());         TextView text =newTextView(getActivity());         int padding =(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,                 4, getActivity().getResources().getDisplayMetrics());         text.setPadding(padding, padding, padding, padding);         scroller.addView(text);         text.setText(Shakespeare.DIALOGUE[getShownIndex()]);         return scroller;     } }
相關文章
相關標籤/搜索