您好,登錄后才能下訂單哦!
本文實例講述了Android開發教程之Fragment定義、創建與使用方法。分享給大家供大家參考,具體如下:
概述
Fragment是activity的界面中的一部分或一種行為。你可以把多個Fragment們組合到一個activity中來創建一個多面界面并且你可以在多個activity中重用一個Fragment。你可以把Fragment認為模塊化的一段activity,它具有自己的生命周期,接收它自己的事件,并可以在activity運行時被添加或刪除。
Fragment不能獨立存在,它必須嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影響。例如:當activity暫停時,它擁有的所有的Fragment們都暫停了,當activity銷毀時,它擁有的所有Fragment們都被銷毀。然而,當activity運行時(在onResume()之后,onPause()之前),你可以單獨地操作每個Fragment,比如添加或刪除它們。當你在執行上述針對Fragment的事務時,你可以將事務添加到一個棧中,這個棧被activity管理,棧中的每一條都是一個Fragment的一次事務。有了這個棧,就可以反向執行Fragment的事務,這樣就可以在Fragment級支持“返回”鍵(向后導航)。
當向activity中添加一個Fragment時,它須置于ViewGroup控件中,并且需定義Fragment自己的界面。你可以在layoutxml文件中聲明Fragment,元素為:<fragment>;也可以在代碼中創建Fragment,然后把它加入到ViewGroup控件中。然而,Fragment不一定非要放在activity的界面中,它可以隱藏在后臺為actvitiy工作。
接下來講如何使用fragment,包括fragment在加入activity的后退棧中時如何保持自己的狀態,如何與activity以及其它fragment們共享事件,如何顯示在activity的動作欄,等等。
Android從3.0開始引入fragment,主要是為了支持更動態更靈活的界面設計,比如在平板上的應用。平板機上擁有比手機更大的屏幕空間來組合和交互界面組件們。Fragment使你在做那樣的設計時,不需應付view樹中復雜的變化。通過把activity的layout分成fragment,你可以在activity運行時改變它的樣子,并且可以在activity的后退棧中保存這些改變。
例如:寫一個讀新聞的程序,可以用一個fragment顯示標題列表,另一個fragment顯示選中標題的內容,這兩個fragment都在一個activity上,并排顯示。那么這兩個fragment都有自己的生命周期并響應自己感興趣的事件。于是,不需再像手機上那樣用一個activity顯示標題列表,用另一個activity顯示新聞內容;現在可以把兩者放在一個activity上同時顯示出來。
Fragment必須被寫成可重用的模塊。因為fragment有自己的layout,自己進行事件響應,擁有自己的生命周期和行為,所以你可以在多個activity中包含同一個Fragment的不同實例。這對于讓你的界面在不同的屏幕尺寸下都能給用戶完美的體驗尤其重要。比如你可以在程序運行于大屏幕中時啟動包含很多fragment的activity,而在運行于小屏幕時啟動一個包含少量fragment的activity。
舉個例子--還是剛才那個讀新聞的程序-當你檢測到程序運行于大屏幕時,啟動activityA,你將標題列表和新聞內容這兩個fragment都放在activityA中;當檢測到程序運行于小屏幕時,還是啟動activityA,但此時A中只有標題列表fragment,當選中一個標題時,activityA啟動activityB,B中含有新聞內容fragment。
Fragments的生命周期
每一個fragments 都有自己的一套生命周期回調方法和處理自己的用戶輸入事件。 對應生命周期可參考下圖:
創建片元(Creating a Fragment)
To create a fragment, you must create a subclass of Fragment (or an existing subclass of it). The Fragment class has code that looks a lot like an Activity. It contains callback methods similar to an activity, such as onCreate(), onStart(), onPause(), and onStop(). In fact, if you're converting an existing Android application to use fragments, you might simply move code from your activity's callback methods into the respective callback methods of your fragment.
要創建一個fragment,必須創建一個fragment的子類(或是繼承自它的子類)。fragment類的代碼看起來很像activity。它與activity一樣都有回調函數,例如onCreate()
,onStart()
,onPause()
,和onStop()
。事實上,如果你正在將一個現成的Android應用轉而使用Fragment來實現,可以簡單的將代碼從activity的回調函數移植到各自的fragment回調函數中。
Usually, you should implement at least the following lifecycle methods:
一般情況下,你至少需要實現以下幾個生命周期方法:
onCreate()
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
在創建fragment時系統會調用此方法。在實現代碼中,你可以初始化想要在fragment中保持的那些必要組件(這里的組件是指除了view之外的東西,比如需要進行界面展示的關鍵數據),當fragment處于暫停或者停止狀態之后可重新啟用它們。
onCreateView()
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.
在第一次為fragment繪制用戶界面時系統會調用此方法。為fragment繪制用戶界面,這個函數必須要返回所繪出的fragment的根View。如果fragment沒有用戶界面可以返回空。
onPause()
The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).
系統回調用該函數作為用戶離開fragment的第一個預兆(盡管這并不總意味著fragment被銷毀)。在當前用戶會話結束之前,通常要在這里提交任何應該持久化的變化(因為用戶可能不再返回)。
Most applications should implement at least these three methods for every fragment, but there are several other callback methods you should also use to handle various stages of the fragment lifecycle. All the lifecycle callback methods are discussed more later, in the section about Handling the Fragment Lifecycle.
大部分應用程序都應該至少為每個fragment實現這三個方法,但是還有許多其他用以操縱fragment生命周期中各個階段的回調函數。所有生命周期中的回調函數在操縱fragment生命周期一節中稍后再做討論。
There are also a few subclasses that you might want to extend, instead of the base Fragment class:
除了基類fragment,這里還有幾個你可能會繼承的子類:
DialogFragment
Displays a floating dialog. Using this class to create a dialog is a good alternative to using the dialog helper methods in the Activity class, because you can incorporate a fragment dialog into the back stack of fragments managed by the activity, allowing the user to return to a dismissed fragment.
顯示一個浮動的對話框。使用這個類創建對話框是使用Activity類對話框工具方法之外的另一個不錯的選擇,因為你可以把fragment對話框并入到由activity管理的fragments后臺棧中,允許用戶返回到一個已經摒棄的fragment。
ListFragment
Displays a list of items that are managed by an adapter (such as a SimpleCursorAdapter), similar to ListActivity. It provides several methods for managing a list view, such as the onListItemClick() callback to handle click events.
顯示一個由適配器管理的條目列表(例如SimpleCursorAdapter),類似于ListActivity。并且提供了許多管理列表視圖的函數,例如處理點擊事件的onListItemClick()回調函數。
PreferenceFragment
Displays a hierarchy of Preference objects as a list, similar to PreferenceActivity. This is useful when creating a "settings" activity for your application.
顯示一個Preference對象的體系結構列表,類似于preferenceActivity。這在為應用程序創建“設置”activity時是很實用的。
實現Fragment的界面
為fragment添加用戶界面:
Fragment一般作為activity的用戶界面的一部分,把它自己的layout嵌入到activity的layout中。 一個
要為fragment提供layout,你必須實現onCreateView()回調方法,然后在這個方法中返回一個View對象,這個對象是fragment的layout的根。
注:如果你的fragment是從ListFragment中派生的,就不需要實現onCreateView()方法了,因為默認的實現已經為你返回了ListView控件對象。
要從onCreateView()方法中返回layout對象,你可以從layoutxml中生成layout對象。為了幫助你這樣做,onCreateView()提供了一個LayoutInflater對象。
舉例:以下代碼展示了一個Fragment的子類如何從layoutxml文件example_fragment.xml中生成對象。
publicstaticclassExampleFragmentextendsFragment{ @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){ //Inflate the layout for this fragment returninflater.inflate(R.layout.example_fragment,container,false); } }
onCreateView()
參數中的container是存放fragment的layout的ViewGroup對象。savedInstanceState參數是一個Bundle,跟activity的onCreate()
中Bundle差不多,用于狀態恢復。但是fragment的onCreate()中也有Bundle參數,所以此處的Bundle中存放的數據與onCreate()中存放的數據還是不同的。至于詳細信息,請參考“操控fragment的生命周期”一節。
Inflate()方法有三個參數:
1 layout的資源ID。
2 存放fragment的layout的ViewGroup。
3 布爾型數據表示是否在創建fragment的layout期間,把layout附加到container上(在這個例子中,因為系統已經把layout插入到container中了,所以值為false,如果為true會導至在最終的layout中創建多余的ViewGroup(這句我看不明白,但我翻譯的應該沒錯))。
現在你看到如何為fragment創建layout了,下面講述如何把它添加到activity中。
把fragment添加到activity
一般情況下,fragment把它的layout作為activitiy的loyout的一部分合并到activity中,有兩種方法將一個fragment添加到activity中:
方法一:在activity的layoutxml文件中聲明fragment
如下代碼,一個activity中包含兩個fragment:
<?xmlversion="1.0"encoding="utf-8"?> <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>
<fragment>中聲明一個fragment。
當系統創建上例中的layout時,它實例化每一個fragment,然后調用它們的onCreateView()方法,以獲取每個fragment的layout。系統把fragment返回的view對象插入到<fragment>元素的位置,直接代替<fragment>元素。
注:每個fragment都需要提供一個ID,系統在activity重新創建時用它來恢復fragment們,你也可以用它來操作fragment進行其它的事物,比如刪除它。有三種方法給fragment提供ID:
1 為android:id
屬性賦一個特定的標識符。
2 為android:tag
屬性賦一個標記名稱。
3如果你沒有使用上述任何一種方法,系統將使用fragment的容器的ID。
方法二:在代碼中添加fragment到一個ViewGroup
這種方法可以在運行時,把fragment添加到activity的layout中。你只需指定一個要包含fragment的ViewGroup。
為了完成fragment的事務(比如添加,刪除,替換等),你必須使用FragmentTransaction的方法。你可以從activity獲取到FragmentTransaction,如下:
FragmentManagerfragmentManager =getFragmentManager() FragmentTransactionfragmentTransaction =fragmentManager.beginTransaction();
然后你可以用add()方法添加一個fragment,它有參數用于指定容納fragment的ViewGroup。如下:
ExampleFragmentfragment =newExampleFragment(); fragmentTransaction.add(R.id.fragment_container,fragment); fragmentTransaction.commit();
Add()的第一個參數是容器ViewGroup,第二個是要添加的fragment。一旦你通過FragmentTransaction對fragment做出了改變,你必須調用方法commit()提交這些改變。
不僅在無界面的fragment中,在有界面的fragment中也可以使用tag來作為為一標志,這樣在需要獲取fragment對象時,要調用findFragmentTag()
。
添加一個沒有界面的fragment
上面演示了如何添加fragment來提供界面,然而,你也可以使用fragment為activity提供后臺的行為而不用顯示fragment的界面。
要添加一個沒有界面的fragment,需在activity中調用方法add(Fragment,String)
(它支持用一個唯一的字符串做為fragment的”tag”,而不是viewID)。這樣添加的fragment由于沒有界面,所以你在實現它時不需調用實現onCreateView()
方法。
使用tag字符串來標識一個fragment并不是只能用于沒有界面的fragment上,你也可以把它用于有界面的fragment上,但是,如果一個fragment沒有界面,tag字符串將成為它唯一的選擇。獲取以tag標識的fragment,需使用方法findFragmentByTab()
。
管理Fragment
要管理fragment們,需使用FragmentManager,要獲取它,需在activity中調用方法getFragmentManager()
。
你可以用FragmentManager來做以上事情:
1 使用方法findFragmentById()
或findFragmentByTag()
,獲取activity中已存在的fragment們。
2 使用方法popBackStack()
從activity的后退棧中彈出fragment們(這可以模擬后退鍵引發的動作)。
3 用方法addOnBackStackChangedListerner()
注冊一個偵聽器以監視后退棧的變化。
你還可以使用FragmentManager打開一個FragmentTransaction來執行fragment的事務,比如添加或刪除fragment。
執行Fragment的事務
在activity中使用fragment的一個偉大的好處是能跟據用戶的輸入對fragment進行添加、刪除、替換以及執行其它動作的能力。你提交的一組fragment的變化叫做一個事務。事務通過FragmentTransaction來執行。你還可以把每個事務保存在activity的后退棧中,這樣就可以讓用戶在fragment變化之間導航(跟在activity之間導航一樣)。
你可以通過FragmentManager來取得FragmentTransaction的實例,如下:
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
一個事務是在同一時刻執行的一組動作(很像數據庫中的事務)。你可以用add()
,remove()
,replace()
等方法構成事務,最后使用commit()
方法提交事務。
在調用commit()
之前,你可以用addToBackStack()
把事務添加到一個后退棧中,這個后退棧屬于所在的activity。有了它,就可以在用戶按下返回鍵時,返回到fragment們執行事務之前的狀態。
如下例:演示了如何用一個fragment代替另一個fragment,同時在后退棧中保存被代替的fragment的狀態。
//Create new fragment and transaction Fragment newFragment = newExampleFragment(); FragmentTransaction transaction=getFragmentManager().beginTransaction(); //Replace whatever is in the fragment_container view with thisfragment, //and add the transaction to the backstack transaction.replace(R.id.fragment_container,newFragment); transaction.addToBackStack(null); //Commit the transaction transaction.commit();
解釋:newFragment代替了控件IDR.id.fragment_container
所指向的ViewGroup中所含的任何fragment。然后調用addToBackStack()
,此時被代替的fragment就被放入后退棧中,于是當用戶按下返回鍵時,事務發生回溯,原先的fragment又回來了。
如果你向事務添加了多個動作,比如多次調用了add()
,remove()
等之后又調用了addToBackStack()
方法,那么所有的在commit()之前調用的方法都被作為一個事務。當用戶按返回鍵時,所有的動作都被反向執行(事務回溯)。
事務中動作的執行順序可隨意,但要注意以下兩點:
1. 你必須最后調用commit()。
2. 如果你添加了多個fragment,那么它們的顯示順序跟添加順序一至(后顯示的覆蓋前面的)。
如果你在執行的事務中有刪除fragment的動作,而且沒有調用addToBackStack()
,那么當事務提交時,那些被刪除的fragment就被銷毀了。反之,那些fragment就不會被銷毀,而是處于停止狀態。當用戶返回時,它們會被恢復。
密技:對于fragment事務,你可以應用動畫。在commit()
之前調用setTransition()
就行。――一般銀我不告訴他哦。
但是,調用commit()后,事務并不會馬上執行。它會在activity的UI線程(其實就是主線程)中等待直到線程能執行的時候才執行(廢話)。如果必要,你可以在UI線程中調用executePendingTransactions()方法來立即執行事務。但一般不需這樣做,除非有其它線程在等待事務的執行。
警告:你只能在activity處于可保存狀態的狀態時,比如running中,onPause()方法和onStop()方法中提交事務,否則會引發異常。這是因為fragment的狀態會丟失。如果要在可能丟失狀態的情況下提交事務,請使用commitAllowingStateLoss()。
Fragment與Activity通訊
盡管fragment的實現是獨立于activity的,可以被用于多個activity,但是每個activity所包含的是同一個fragment的不同的實例。
Fragment可以調用getActivity()方法很容易的得到它所在的activity的對象,然后就可以查找activity中的控件們(findViewById()
)。例如:
ViewlistView =getActivity().findViewById(R.id.list);
同樣的,activity也可以通過FragmentManager的方法查找它所包含的frament們。例如:
ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment)
activity響應fragment的事件
有時,你可能需要fragment與activity共享事件。一個好辦法是在fragment中定義一個回調接口,然后在activity中實現之。
例如,還是那個新聞程序的例子,它有一個activity,activity中含有兩個fragment。fragmentA顯示新聞標題,fragmentB顯示標題對應的內容。fragmentA必須在用戶選擇了某個標題時告訴activity,然后activity再告訴fragmentB,fragmentB就顯示出對應的內容(為什么這么麻煩?直接fragmentA告訴fragmentB不就行了?也可以啊,但是你的fragment就減少了可重用的能力。現在我只需把我的事件告訴宿主,由宿主決定如何處置,這樣是不是重用性更好呢?)。如下例,OnArticleSelectedListener接口在fragmentA中定義:
public static class FragmentA extends ListFragment{ ... //Container Activity must implement this interface public interface OnArticleSelectedListener{ public void onArticleSelected(Uri articleUri); } ...
然后activity實現接口OnArticleSelectedListener,在方法onArticleSelected()
中通知fragmentB。當fragment添加到activity中時,會調用fragment的方法onAttach()
,這個方法中適合檢查activity是否實現了OnArticleSelectedListener接口,檢查方法就是對傳入的activity的實例進行類型轉換,如下所示:
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity){ super.onAttach(activity); try{ mListener =(OnArticleSelectedListener)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString()+"must implement OnArticleSelectedListener"); } } ...
如果activity沒有實現那個接口,fragment拋出ClassCastException異常。如果成功了,mListener成員變量保存OnArticleSelectedListener的實例。于是fragmentA就可以調用mListener的方法來與activity共享事件。例如,如果fragmentA是一個ListFragment,每次選中列表的一項時,就會調用fragmentA的onListItemClick()
方法,在這個方法中調用onArticleSelected()
來與activity共享事件,如下:
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l,View v,int position,long id){ //Append the clicked item's row ID with the content provider Uri Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI,id); //Send the event and Uri to the host activity mListener.onArticleSelected(noteUri); } ...
onListItemClick()
傳入的參數id是列表的被選中的行ID,另一個fragment用這個ID來從程序的ContentProvider中取得標題的內容。
Fragement應用示例
把條目添加到動作欄
你的fragment們可以向activity的菜單(按Manu鍵時出現的東西)添加項,同時也可向動作欄(界面中頂部的那個區域)添加條目,這都需通過實現方法onCreateOptionManu()
來完成。
你從fragment添加到菜單的任何條目,都會出現在現有菜單項之后。Fragment之后可以通過方法onOptionsItemSelected()
來響應自己的菜單項被選擇的事件。
你也可以在fragemnt中注冊一個view來提供快捷菜單(上下文菜單)。當用戶要打開快捷菜單時,fragment的onCreateContextMenu()
方法會被調用。當用戶選擇其中一項時,fragemnt的onContextItemSelected()
方法會被調用。
注:盡管你的fragment可以分別收到它所添加的菜單項的選中事件,但是activity才是第一個接收這些事件的家伙,只有當activity對某個事件置之不理時,fragment才能接收到這個事件,對于菜單和快捷菜單都是這樣。
下例中實驗了之前所講的所有內容。此例有一個activity,其含有兩個fragment。一個顯示莎士比亞劇的播放曲目,另一個顯示選中曲目的摘要。此例還演示了如何跟據屏幕大小配置fragment。
MainActivity:
@Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_layout); }
Layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/details" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" android:background="?android:attr/detailsElementBackground" /> </LinearLayout>
系統在activity加載此layout時初始化TitlesFragment(用于顯示標題列表),TitlesFragment的右邊是一個FrameLayout,用于存放顯示摘要的fragment,但是現在它還是空的,fragment只有當用戶選擇了一項標題后,摘要fragment才會被放到FrameLayout中。
然而,并不是所有的屏幕都有足夠的寬度來容納標題列表和摘要。所以,上述layout只用于橫屏,現把它存放于ret/layout-land/fragment_layout.xml。
之外,當用于豎屏時,系統使用下面的layout,它存放于ret/layout/fragment_layout.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
這個layout只包含TitlesFragment。這表示當使用豎屏時,只顯示標題列表。當用戶選中一項時,程序會啟動一個新的activity去顯示摘要,而不是加載第二個fragment。
下一步,你會看到Fragment類的實現。第一個是TitlesFragment,它從ListFragment派生,大部分列表的功能由ListFragment提供。
當用戶選擇一個Title時,代碼需要做出兩種行為,一種是在同一個activity中顯示創建并顯示摘要fragment,另一種是啟動一個新的activity。
public static class TitlesFragment extends ListFragment { boolean mDualPane; int mCurCheckPosition = 0; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Populate list with our static array of titles. setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES)); // Check to see if we have a frame in which to embed the details // fragment directly in the containing UI. View detailsFrame = getActivity().findViewById(R.id.details); mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE; if (savedInstanceState != null) { // Restore last state for checked position. 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 public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition); } @Override public void 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) { // Make new fragment to show this selection. details = DetailsFragment.newInstance(index); // Execute a transaction, replacing any existing fragment // with this one inside the frame. FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.details, details); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } } else { // Otherwise we need to launch a new activity to display // the dialog fragment with selected text. Intent intent = new Intent(); intent.setClass(getActivity(), DetailsActivity.class); intent.putExtra("index", index); startActivity(intent); } } }
第二個fragment,DetailsFragment顯示被選擇的Title的摘要:
public static class DetailsFragment extends Fragment { /** * Create a new instance of DetailsFragment, initialized to * show the text at 'index'. */ public static DetailsFragment newInstance(int index) { DetailsFragment f = new DetailsFragment(); // Supply index input as an argument. Bundle args = new Bundle(); args.putInt("index", index); f.setArguments(args); return f; } public int getShownIndex() { return getArguments().getInt("index", 0); } @Override public View 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. return null; } ScrollView scroller = new ScrollView(getActivity()); TextView text = new TextView(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; } }
如果當前的layout沒有R.id.detailsView
(它被用于DetailsFragment的容器),那么程序就啟動DetailsActivity來顯示摘要。
下面是DetailsActivity,它只是簡單地嵌入DetailsFragment來顯示摘要。
public static class DetailsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { // If the screen is now in landscape mode, we can show the // dialog in-line with the list so we don't need this activity. finish(); return; } if (savedInstanceState == null) { // During initial setup, plug in the details fragment. DetailsFragment details = new DetailsFragment(); details.setArguments(getIntent().getExtras()); getFragmentManager().beginTransaction().add(android.R.id.content, details).commit(); } } }
注意這個activity在檢測到是豎屏時會結束自己,于是主activity會接管它并顯示出TitlesFragment和DetailsFragment。這可以在用戶在豎屏時顯示在TitleFragment,但用戶旋轉了屏幕,使顯示變成了橫屏。
更多關于Android相關內容感興趣的讀者可查看本站專題:《Android基本組件用法總結》、《Android開發入門與進階教程》、《Android布局layout技巧總結》、《Android視圖View技巧總結》、《Android編程之activity操作技巧總結》、《Android資源操作技巧匯總》及《Android控件用法總結》
希望本文所述對大家Android程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。