Fragments碎片

A Fragment represents a behavior or a portion of user interface in an Activity.html

在一個Activity活動中,一個Fragment表明一個行爲或者用戶界面的一部分java

You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities.android

你能夠將多個碎片組合到一個活動中,來構成多面UI並能夠在多個活動中重複使用一個碎片編程

You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities).api

你能夠將一個碎片當成一個活動的模塊化的部分,它有本身生命週期,接收它本身捅有的輸入事件,而且當活動正在運行時,你能夠增長和移除它(稍稍有點像是,能夠在不一樣的活動中重複使用的子活動)。sass

A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle.session

一個碎片老是嵌入到一個活動中的,而且碎片的生命週期直接由捅有它的主活動的生命週期所影響app

For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments.less

好比,當活動被暫停了,那麼全部其中的片段也會暫停,而且當活動被中止了,因此全部的碎片也被中止了ide

However, while an activity is running (it is in the resumed lifecycle state), you can manipulate each fragment independently, such as add or remove them.

然而,當一個活動正在運行(它處恢復的生命週期狀態),你能夠獨立的操做每一個碎片,好比增長或者移除它們

When you perform such a fragment transaction, you can also add it to a back stack that's managed by the activity—each back stack entry in the activity is a record of the fragment transaction that occurred.

當你運行這樣一個碎片事務時,你也能夠把它加入到由activity管理的返回堆中,在活動中每一個返回堆的入點是每一個碎片事務發生的一個記錄.

The back stack allows the user to reverse a fragment transaction (navigate backwards), by pressing the BACK button.

在按返回鍵時,返回堆容許用反轉碎片事務(導航返回)

When you add a fragment as a part of your activity layout, it lives in a ViewGroup inside the activity's view hierarchy and the fragment defines its own view layout.

當你把一個碎片,加入到你的活動佈局中的一部分時,它存在於一個嵌入了活動的視圖層級的ViewGroup中.而且碎片定義它本身的視圖佈局

You can insert a fragment into your activity layout by declaring the fragment in the activity's layout file, as a <fragment> element, or from your application code by adding it to an existing ViewGroup.

你能夠用<fragment> 元素,在活動的佈局文件中聲明一個碎片,插入到你的活動的佈局中,或者在應用代碼中,把它加入到一個ViewGroup中.

However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.

然而,一個碎片不是活動佈局必需要求的一部分,你也能夠用一個沒有它本身的UI的碎片,把它當成活動的一個不可見的工做者.

This document describes how to build your application to use fragments, including how fragments can maintain their state when added to the activity's back stack, share events with the activity and other fragments in the activity, contribute to the activity's action bar, and more.

這個文檔描述了,如何構建一個應用來使用碎片,包括把碎片加入到活動的返回堆時,怎樣維持它們的狀態.與活動和該活動的其餘碎片共享事件,構成(促成)活動的動做條等.

 

 

Design Philosophy設置理念

Android introduced fragments in Android 3.0 (API level 11), primarily to support more dynamic and flexible UI designs on large screens, such as tablets.

Android在3.0中包含了碎片,主要是爲在大屏幕布中支持更加動態和靈活的UI,好比平板電腦

Because a tablet's screen is much larger than that of a handset, there's more room to combine and interchange UI components.

由於平板電腦的屏幕布比手持設備大不少,它有更多的空間來組合和交換UI組件

Fragments allow such designs without the need for you to manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, you become able to modify the activity's appearance at runtime and preserve those changes in a back stack that's managed by the activity.

碎片的設計,能使你不須要管理複雜的視圖層的的改變.經過把你的視圖佈局分紅碎片,你就能在運行時修改活動的顯示,而且把這些改變保存在由活動管理的一個返回堆中.

For example, a news application can use one fragment to show a list of articles on the left and another fragment to display an article on the right—both fragments appear in one activity, side by side, and each fragment has its own set of lifecycle callback methods and handle their own user input events.

好比,一個新的應用,能夠用一個碎片在左邊,顯示一個文件列表,而且用另外一個碎片,在右邊顯示文章-----兩個碎片並排出如今一個活動中,而且每一個碎片捅有它本身的生命週期回調方法,並處理它們捅有的用戶事件.

Thus, instead of using one activity to select an article and another activity to read the article, the user can select an article and read it all within the same activity, as illustrated in the tablet layout in figure 1.

所以,用戶就能在同一個活動中選擇文章並閱它,而不須要用一個活動選一篇文章,另外一個活動去讀取文章.就像圖1中平板電腦佈局中顯示的同樣.

You should design each fragment as a modular and reusable activity component. 你應該把每個碎片設計成一個模塊化的可重用的活動組件.

That is, because each fragment defines its own layout and its own behavior with its own lifecycle callbacks, you can include one fragment in multiple activities, so you should design for reuse and avoid directly manipulating one fragment from another fragment.

由於每個碎片定義了它本身的佈局和它本身的行爲,及它本身的生命回調函數,你能夠在多個活動中包含一個碎片,因此你應把它設計成可重複使用,而且避免直接從一個碎片中操做另外一個碎片.

This is especially important because a modular fragment allows you to change your fragment combinations for different screen sizes. When designing your application to support both tablets and handsets,

當你設計你的應用能同時支持手持設備和平板電腦時;這一點很是重要,由於一個模塊化的碎片,使得你能根據不一樣的屏幕布大小來改變你的碎片的組合.

you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space.

你能在不一樣佈局配置中重複使用你的碎片,來基於不一樣屏幕空間優化用戶的體驗.

For example, on a handset, it might be necessary to separate fragments to provide a single-pane UI when more than one cannot fit within the same activity.

好比,在一個手持設備中,可能必要把一個碎片從單個UI中分離出來,由於在一個活動中,不適合多一個碎片.

 

Figure 1. An example of how two UI modules defined by fragments can be combined into one activity for a tablet design, but separated for a handset design.

圖1,說明了,兩個碎片UI模塊在平板電腦中,怎樣結合到一個活動中,但在手持設備中是怎樣分開的.

For example—to continue with the news application example—the application can embed two fragments in Activity A, when running on a tablet-sized device.

好比----繼續使用新聞應用的例子,當在平板電腦中運行時,這個應用能夠嵌入兩個碎片到活動A中,

However, on a handset-sized screen, there's not be enough room for both fragments,

但時,在手持設備屏幕中,沒有足夠的空間放兩個碎片

so Activity A includes only the fragment for the list of articles, and when the user selects an article, it starts Activity B, which includes the second fragment to read the article.
因此活動A,只包括顯示文章列表的碎片,並當用戶選擇了一篇文章時,它啓動活動B,而活動B包括了讀取文章的第二個碎片.                                                                                Thus, the application supports both tablets and handsets by reusing fragments in different combinations, as illustrated in figure 1.所以,就像圖1同樣,應用經過重用碎片的不一樣組合,來同時支持平板電腦和手持設備.For more information about designing your application with different fragment combinations for different screen configurations, see the guide to Supporting Tablets and Handsets.更多關於使用不一樣碎片組合,來設計你的應用支持不一樣屏幕配置的信息,請看Supporting Tablets and Handsets.

 

Creating a Fragment建立碎片

Figure 2. The lifecycle of a fragment (while its activity is running).碎片的生命週期(當活動運行時)

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. 要建立碎片,你必須建立一個Fragment子類(或者它存在的子類),Fragment類的代碼看起來像是一個Activity類.It contains callback methods similar to an activity, such as onCreate(), onStart(), onPause(), and onStop(). 它包含相似於活動的回調方法,好比 onCreate(), onStart(), onPause(),和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.事實上,若是你打算把一個已存在的Android應用,轉換成用碎片來實現,你可能只須簡單的把你的活動的回調方法中的代碼移動到你的碎片的相應的回調方法中.(便可)

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.在你的實現中,你應初始化,當碎片暫停,或者中止,而後恢復時,你想要保留的碎片的關鍵組件.
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. 爲了讓你的碎片畫UI,你必須從這個方法中,返回你的碎片佈局的根視圖( View),You can return null if the fragment does not provide a UI.若是碎片不提供UI,你能夠返回空(null)
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).這裏一般是你應該提交超出當前用戶任務外須要保存的持久數據的地方(由於用戶可能不會返回).

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.全部處理生命週期的回調方法,將在Handling the Fragment Lifecycle部分有更多詳細的討論.

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,使用這個類建立對話框是,使用 Activity類中的對話框的可選的好方法. 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.由於你能夠把這個碎片對話框合併到由活動管理的碎片返回堆中,這樣能容許用戶返回到消失的碎片上.
ListFragment
Displays a list of items that are managed by an adapter (such as a SimpleCursorAdapter), similar to ListActivity. 顯示由適配器管理的項目列表(像一個 SimpleCursorAdapter),相似於 ListActivity類.It provides several methods for managing a list view, such as the onListItemClick() callback to handle click events.它提供了幾個管理列表視圖的方法,好比處理點擊事件的 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類,當爲你的應用建立"setting設置"活動時,這是很是有用的.
Adding a user interface增長用戶界面

A fragment is usually used as part of an activity's user interface and contributes its own layout to the activity.一個碎片經常使用來當成一個活動的用戶界面的一部分,並把它本身的佈局貢獻給活動.

To provide a layout for a fragment, you must implement the onCreateView() callback method, 爲了給一個碎片提供一個佈局,你必須實現onCreateView()回調方法,which the Android system calls when it's time for the fragment to draw its layout. 當碎片須要畫它的佈局時,系統調用它.Your implementation of this method must return a View that is the root of your fragment's layout.你的這個方法的實現,必須返回你的碎片佈局的,根視圖(View)

Note: If your fragment is a subclass of ListFragment, the default implementation returns a ListView from onCreateView(), so you don't need to implement it.注意:若是你的碎片是一個ListFragment類的子類,默認實現從onCreateView()方法返回一個ListView,因此你不須要實現他

To return a layout from onCreateView(), you can inflate it from a layout resource defined in XML. To help you do so, onCreateView() provides a LayoutInflater object.爲了返回一個佈局,你能夠展開定義在XML文件中的佈局資源(layout resource).爲了幫助你這麼作(實現他),onCreateView()方法提供了一個LayoutInflater類的對像

For example, here's a subclass of Fragment that loads a layout from the example_fragment.xml file:好比,這裏是一個Fragment類的子類從一個example_fragment.xml資源文件中加載一個佈局的例子

public static class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}

 

 

Creating a layout建立佈局

In the sample above, 在上面的例子中R.layout.example_fragment is a reference to a layout resource named example_fragment.xml saved in the application resources.R.layout.example_fragment是一個叫example_fragment.xml佈局資源的引用,保存在應用資源中 For information about how to create a layout in XML, see the User Interface documentation.關於如何在XML文件中建立一個布避,看User Interface用戶界面文檔

 

The container parameter passed to onCreateView() is the parent ViewGroup (from the activity's layout) 傳遞給onCreateView()方法的container容器參數是父類ViewGroup(來自活動的佈局),in which your fragment layout will be inserted. 在那裏將插入你的碎片佈局.The savedInstanceState parameter is a Bundle that provides data about the previous instance of the fragment, if the fragment is being resumed 若是碎片即將被恢復,這個savedInstanceState參數是一個類,它提供關於前一個碎片實例的數據(restoring state is discussed more in the section about Handling the Fragment Lifecycle).(在Handling the Fragment Lifecycle部分將更詳細的討論重關於新存儲狀態)

The inflate() method takes three arguments:inflate()展開方法包括三個參數

  • The resource ID of the layout you want to inflate.你想要展開的佈局資源ID.
  • The ViewGroup to be the parent of the inflated layout. ViewGroup是展開佈局的父類 Passing the container is important in order for the system to apply layout parameters to the root view of the inflated layout, specified by the parent view in which it's going.爲了讓系統將佈局參數應用到展開的佈局的根視圖上,傳遞container是很是重要,它是由父視圖指定(這句很差理解)
  • A boolean indicating whether the inflated layout should be attached to the ViewGroup (the second parameter) during inflation. 一個布爾值,指示是否展開的佈局應該附屬到ViewGroup上(In this case, this is false because the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout.)在這個例子中,這個值是false ,由於系統已經插入一個展開的視圖到容器中---傳遞真值,將致使在最終的視圖上建立一個冗餘的視圖組.

Now you've seen how to create a fragment that provides a layout. Next, you need to add the fragment to your activity.如今,你已經看到了如何建立一個提供佈局的碎片了,下一步,你須要將這個碎片加入到你的活動中.

Adding a fragment to an activity加入一個碎片到一個活動中

Usually, a fragment contributes a portion of UI to the host activity, which is embedded as a part of the activity's overall view hierarchy. 一般,一個碎片致力於成爲宿主活動UI的一部分,There are two ways you can add a fragment to the activity layout:你能夠有兩個方法來加入一個碎片到活動佈局中

  • Declare the fragment inside the activity's layout file.在活動的佈局文件中聲明碎片

    In this case, you can specify layout properties for the fragment as if it were a view. 在這個例子中,若是碎片是一個視圖,你能夠爲碎片指定佈局屬性.For example, here's the layout file for an activity with two fragments:好比這是一個含有兩個碎片的,活動的佈局文件的例子

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

    The android:name attribute in the <fragment> specifies the Fragment class to instantiate in the layout.在<fragment>中的android:name這個屬性,指定了在佈局文件中Fragment 類的實例化.

    When the system creates this activity layout, it instantiates each fragment specified in the layout and calls the onCreateView() method for each one, to retrieve each fragment's layout. 當繫系建立這個活動佈局時,它實例化佈局文件中指定的每個碎片,而且爲每一個碎片調用方法能,來提取每一個碎片的佈局,The system inserts the View returned by the fragment directly in place of the <fragment> element.系統將插入<fragment>元素那兒,由碎片直接返回的視圖(View )

    Note: Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). 注意:每一個碎片必需要求一個惟一的身份,若是活動重啓時,系統能夠用它來恢復碎片(而且,你能常常捕獲碎片來執行事務,好比移除它)There are three ways to provide an ID for a fragment:有三個方法來給碎片提供一個ID:

    • Supply the android:id attribute with a unique ID.給android:id屬性提供一個惟一的DI
    • Supply the android:tag attribute with a unique string.給囑性提供一個惟一的字串
    • If you provide neither of the previous two, the system uses the ID of the container view.若是上面有兩個你都不用,系統將使用容器視圖的ID
  • Or, programmatically add the fragment to an existing ViewGroup.或者,可編程的加入一個碎片到一個存在的ViewGroup

    At any time while your activity is running, you can add fragments to your activity layout. You simply need to specify a ViewGroup in which to place the fragment.在你的activity運行的任意時刻,你能夠添加碎片到你的佈局中,你只要簡單的爲你的碎片指定一個ViewGroup,在其中放入你的碎片To make fragment transactions in your activity (such as add, remove, or replace a fragment), you must use APIs from FragmentTransaction.爲了處理碎片事務(好比添加,移除,或者替換碎片),你必要使用FragmentTransaction的APIs .You can get an instance of FragmentTransaction from your Activity like this:你能夠從你的Activity活動中獲得一個FragmentTransaction實例.

    FragmentManager fragmentManager = 
    FragmentTransaction fragmentTransaction = fragmentManager.;getFragmentManager()beginTransaction()

    You can then add a fragment using the add() method, specifying the fragment to add and the view in which to insert it. For example:你能夠用方法加入一個碎片,並指定要加入的碎片和插入到那裏.

    ExampleFragment fragment = new ExampleFragment();//新建一個碎片
    fragmentTransaction.add(R.id.fragment_container, fragment);//第一個是容器,第二個參數是碎片
    fragmentTransaction.commit();//提交

    The first argument passed to add() is the ViewGroup in which the fragment should be placed, specified by resource ID, and the second parameter is the fragment to add.傳給add()方法的,第一個參數是ViewGroup視圖組類,碎片將放在這裏,它由資源ID指定,而且第二個參數是要加入的碎片

    Once you've made your changes with FragmentTransaction, you must call commit() for the changes to take effect.一旦你用FragmentTransaction改變了你的碎片的事務,你必須調用commit()方法,使得改變生效.

Adding a fragment without a UI增長沒有UI的碎片

The examples above show how to add a fragment to your activity in order to provide a UI. 上面的這個例子展現了爲了提供一個UI,怎樣把一個碎片加入到你的活動中.However, you can also use a fragment to provide a background behavior for the activity without presenting additional UI.然而,你也可使用一個沒有顯示UI的碎片,爲你的活動提供一個後臺行爲.

To add a fragment without a UI, add the fragment from the activity using add(Fragment, String) (supplying a unique string "tag" for the fragment, rather than a view ID).要加入一個沒有UI的碎片,從activity中使用方法加入碎片(爲碎片,提供一個惟一的字串"tag",而不是視圖ID) This adds the fragment, but, because it's not associated with a view in the activity layout, it does not receive a call to onCreateView(). So you don't need to implement that method.但時,這樣增長的碎片,沒有關聯到活動的佈局,它不會從方onCreateView()法接收一個調用,因此你不須要實現onCreateView()方法.

Supplying a string tag for the fragment isn't strictly for non-UI fragments爲碎片提供字串tag不只僅限於沒有UI的碎片—you can also supply string tags to fragments that do have a UI你也能夠爲有UI的碎片提供字串—but if the fragment does not have a UI, then the string tag is the only way to identify it可是若是碎片沒有UI,那麼字串tag是惟一能標識它的方法. If you want to get the fragment from the activity later, you need to use findFragmentByTag().後續,若是你想要從activity中得到這個碎片,那麼你得用這個findFragmentByTag()方法.

For an example activity that uses a fragment as a background worker, without a UI, see the FragmentRetainInstance.java sample.想要看一個活動把碎片當成後臺工做者的方法,請看 FragmentRetainInstance.java 例子.

Managing Fragments管理碎片

To manage the fragments in your activity, you need to use FragmentManager. To get it, call getFragmentManager() from your activity.要在你的活動中管理碎片,你須要用FragmentManager.要獲得它,你得用getFragmentManager()方法.

Some things that you can do with FragmentManager include:你能夠用FragmentManager類作的事情包括:

  • Get fragments that exist in the activity, with findFragmentById() (for fragments that provide a UI in the activity layout) or findFragmentByTag() (for fragments that do or don't provide a UI)獲取在活動中存大的碎片,用方法(用於在UI佈局中提供UI的碎片),或者用findFragmentByTag()方法(用於提供了或沒有提供UI的碎片).
  • Pop fragments off the back stack, with popBackStack() (simulating a BACK command by the user).從返回堆中彈出碎片,用方法(相似於用戶用BACK命令)
  • Register a listener for changes to the back stack, with addOnBackStackChangedListener().爲改變返回堆註冊一個監聽器,用addOnBackStackChangedListener()方法.

For more information about these methods and others, refer to the FragmentManager class documentation.關於這些和其餘方法的更多信息,參考FragmentManager類文檔

As demonstrated in the previous section, you can also use FragmentManager to open a FragmentTransaction, which allows you to perform transactions, such as add and remove fragments.就像上面部分所講的,你能夠用FragmentManager類,來打開一個FragmentTransaction事務,它能讓你執行事務,好比移除碎片

Performing Fragment Transactions執行碎片事務

A great feature about using fragments in your activity is the ability to add, remove, replace, and perform other actions with them, in response to user interaction.在你的活動中使用碎片的最大的好處是,在響應用戶的交互時,能進行增長,移除,替換及其餘的動做. Each set of changes that you commit to the activity is called a transaction and you can perform one using APIs in FragmentTransaction. 每一個你提交到活動的一套改變,叫作事務,而且你能在FragmentTransaction中使用APIs執行一個.You can also save each transaction to a back stack managed by the activity, allowing the user to navigate backward through the fragment changes (similar to navigating backward through activities).你也能夠把它們保存到由活動管理的返回堆中,經過碎片的改變容許用戶導航返回(相似於導航返回到你的活動)

You can acquire an instance of FragmentTransaction from the FragmentManager like this:你能夠像這樣從FragmentManager碎片管理器那裏獲得一個FragmentTransaction的實例:

FragmentManager fragmentManager = ;
FragmentTransaction fragmentTransaction = fragmentManager.;getFragmentManager()beginTransaction()

Each transaction is a set of changes that you want to perform at the same time. 每一個事務是你想要同時執行的一套改變.You can set up all the changes you want to perform for a given transaction using methods such as add(), remove(), and replace(). 你可使用這些方法,爲某個指定的事務,設置全部你想要執行的改變Then, to apply the transaction to the activity, you must call commit().而後,應用這些改變到你的活動,你必須用commit()方法.

Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. 然而,在你調用commit()方法前,爲了加入事務到碎片事務返回堆,你可能想要調用addToBackStack()方法,This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the BACK key.這個返回堆由活動管理,它能容許用戶按BACK鍵返回到前一個碎片狀態.

For example, here's how you can replace one fragment with another, and preserve the previous state in the back stack:好比,這裏的例子是,你怎麼用一個碎片替換另外一個碎片,並把前一個狀態保存到返回堆

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

In this example, newFragment replaces whatever fragment (if any) is currently in the layout container identified by the R.id.fragment_container ID. 在這個例子中,新的碎片替換了(R.id.fragment_container)佈局容器中的任意碎片.By calling addToBackStack(), the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the BACK key.經過調用方法,替換事務被保存在返回堆中,因此用戶按下BACK鍵,能夠反轉這個事務到前一個碎片.

If you add multiple changes to the transaction (such as another add() or remove()) and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the BACK key will reverse them all together.若是你加入多個改變到事務(好比其餘add()或者remove())關且調用addToBackStack().在你提交全部改變前,它們被當成一個事務加入到返回堆,而且按BACK鍵,將把它們一塊兒反轉.

The order in which you add changes to a FragmentTransaction doesn't matter, except:你加入到事務的全部改變的先後順序,可有可無,除了:

  • You must call commit() last你必須最後調用方
  • If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy若是你加入多個碎片到同一個容器,那麼你加入它們的順序決定了它們在視圖層次中出現的順序.

If you do not call addToBackStack() when you perform a transaction that removes a fragment, then that fragment is destroyed when the transaction is committed and the user cannot navigate back to it. 當你執行一個移除碎片的事務時,若是你沒有調用addToBackStack()方法,那麼當事務被提交時,那個碎片被銷燬了.而且用戶不能導航返回到那個碎片.Whereas, if you do call addToBackStack() when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back.當要移除一個碎片時,若是你調用了addToBackStack()方法,那麼該碎片被中止了,而且若是用戶導航返回,它將被恢復.

Tip: For each fragment transaction, you can apply a transition animation, by calling setTransition() before you commit.在你提交前,經過調用setTransition()方法.能夠對每一個碎片的轉換,應用轉換動畫,

Calling commit() does not perform the transaction immediately. Rather, it schedules it to run on the activity's UI thread (the "main" thread) as soon as the thread is able to do so.調用方法並非當即執行轉換,而是一旦主線程可以運行它時,就把它加入活動UI線程(主線程)的運行表裏(schedules), If necessary, however, you may call executePendingTransactions() from your UI thread to immediately execute transactions submitted by commit().但如果必須的話,你能夠從你的活動UI線程中,調用executePendingTransactions()方法當即執行由commit()提交的轉換(transactions) Doing so is usually not necessary unless the transaction is a dependency for jobs in other threads.這樣作一般是不須要的,除非這個轉換由於一些工做依賴其餘的線程.

Caution: You can commit a transaction using commit() only prior to the activity saving its state (when the user leaves the activity).注意,你只能在活動保存它的狀態以前(當用戶),用commit()方法提交事務. If you attempt to commit after that point, an exception will be thrown. 若是你嘗試那個點以後提交,會拋出一個異常.This is because the state after the commit can be lost if the activity needs to be restored.這是由於若是活動須要恢復,提交後的狀態丟失了. For situations in which its okay that you lose the commit, use commitAllowingStateLoss().對於你的提交能夠被丟掉的狀況,那麼你就用commitAllowingStateLoss()方法.

Communicating with the Activity與活動通訊

Although a Fragment is implemented as an object that's independent from an Activity and can be used inside multiple activities, a given instance of a fragment is directly tied to the activity that contains it.雖然Fragment是看成一個獨立於Activity的對象實現的,而且能夠插入到多個活動,但一個給定的對象,是直接捆邦包含它的活動上的。

Specifically, the fragment can access the Activity instance with getActivity() and easily perform tasks such as find a view in the activity layout:特別是,該碎片經過使用方法能訪問實例子,而且能很容易的執行像從活動佈局中尋找一個視圖這樣的任務:

View listView = getActivity().findViewById(R.id.list);

Likewise, your activity can call methods in the fragment by acquiring a reference to the Fragment from FragmentManager, using findFragmentById() or findFragmentByTag(). For example:一樣,你的活動可通findFragmentById()或者findFragmentByTag()方法從FragmentManager中查詢的Fragment引用,調用碎片裏的方法,好比:

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

Creating event callbacks to the activity建立活動的事件回調方法

In some cases, you might need a fragment to share events with the activity.在有些狀況下,你可能須要一個碎片與活動共享事件. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it.一個比較好的辦法就是在碎片中插入一個回調接口,而且請求宿主活動實現它。 When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.當一個活動經過接口收到一個回調(事件),若是必要的話,它就能夠同佈局中的其餘碎片共享信息

For example, if a news application has two fragments in an activity—one to show a list of articles (fragment A) and another to display an article (fragment B)—then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article. 好比說,若是一個應用在一個活動中有兩個碎片,一個用於顯示文章列表(碎片A),而且另外一個用於顯示文章內容(碎片B)---然而,碎片A必須告訴碎片B,列表中的那一項被選中了,好讓碎片B能顯示選中項所對應的文章,In this case, the OnArticleSelectedListener interface is declared inside fragment A:在這種狀況下,碎片A中聲明瞭OnArticleSelectedListener 監聽接口:

 
public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    ...
}

Then the activity that hosts the fragment implements the OnArticleSelectedListener interface and overrides onArticleSelected() to notify fragment B of the event from fragment A. 該碎片的宿主活動,實現OnArticleSelectedListener 接口並複寫onArticleSelected()方法,告訴碎片B一個來自碎片A的事件To ensure that the host activity implements this interface, fragment A's onAttach() callback method (which the system calls when adding the fragment to the activity) instantiates an instance of OnArticleSelectedListener by casting the Activity that is passed into onAttach():爲了保證宿主活動實現這個實例,碎片AonAttach() 回調方法(當把該碎片加入到該活動時系統會調用該方法),通傳給onAttach()方法該Activity,並把它拋出。

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;//活動必須實現OnArticleSelectedListener接口,不然轉換異常
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");//發生異常時拋出
        }
    }
    ...
}

If the activity has not implemented the interface, then the fragment throws a ClassCastException. 若是該活動沒有實現該接口,那麼碎片會拋出一個ClassCastException異常。On success, the mListener member holds a reference to activity's implementation of OnArticleSelectedListener, so that fragment A can share events with the activity by calling methods defined by the OnArticleSelectedListener interface.在成功的狀況下,mListener 的成員持有活動的OnArticleSelectedListener實現的引用 For example, if fragment A is an extension of ListFragment, each time the user clicks a list item, the system calls onListItemClick() in the fragment, which then calls onArticleSelected() to share the event with the activity:好比,若是一個碎片A繼承了ListFragment類,每次用戶點擊一個列表項,系統調用碎片中的onListItemClick()方法,並在該方法中調用onArticleSelected()方法,來與活動共享事件

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);//把選定的列表項ID,包裹成Uri
        // Send the event and Uri to the host activity
        mListener.onArticleSelected(noteUri);//經過該方法發送到活動,活動實現了這個方法,而後解釋該Uri,再傳給該活動的其餘碎片
    }
    ...
}

The id parameter passed to onListItemClick() is the row ID of the clicked item, which the activity (or other fragment) uses to fetch the article from the application's ContentProvider.傳給onListItemClick())方法的id參數是點擊項的行ID.活動將用該ID,從應用的內容提供者ContentProvider獲取文章.

More information about using a content provider is available in the Content Providers document.關於怎樣使用內容提供者請看Content Providers 文檔

Adding items to the Action Bar把items 增長到動做Bar

Your fragments can contribute menu items to the activity's Options Menu (and, consequently, the Action Bar) by implementing onCreateOptionsMenu().你的碎片能夠經過實現onCreateOptionsMenu()方法把菜單項貢獻給活動Options Menu可選菜單(而且,一樣,可貢獻給Action Bar) In order for this method to receive calls, however, you must call setHasOptionsMenu() during onCreate(), to indicate that the fragment would like to add items to the Options Menu (otherwise, the fragment will not receive a call to onCreateOptionsMenu()).然而,爲了讓這個方法收到調用,你必須在onCreate()裏調用setHasOptionsMenu()方法,來表示碎片想加入items項到可選菜單中(不然,碎片將不能收到來自onCreateOptionsMenu()的調用)

Any items that you then add to the Options Menu from the fragment are appended to the existing menu items. 全部你後面加入到可選菜單的項,將會加入到已存大的菜單項中The fragment also receives callbacks to onOptionsItemSelected() when a menu item is selected.當菜單項被選中時,碎片也會收到onOptionsItemSelected()的回調.

You can also register a view in your fragment layout to provide a context menu by calling registerForContextMenu(). 你也能夠調用registerForContextMenu()方法,將你碎片佈局中的視圖註冊到上下文菜單,When the user opens the context menu, the fragment receives a call to onCreateContextMenu(). 當用戶打開上下文菜單,碎片將收到來自onCreateContextMenu()方法的調用When the user selects an item, the fragment receives a call to onContextItemSelected().當用戶選擇一個項時,碎片將收到onContextItemSelected()調用.

Note: Although your fragment receives an on-item-selected callback for each menu item it adds, the activity is first to receive the respective callback when the user selects a menu item. 當用戶選中一個菜單項時,雖然你的碎片收到它加入的到菜單的每個項的響應item的回調,但活動首先收到相應的回調.If the activity's implementation of the on-item-selected callback does not handle the selected item, then the event is passed to the fragment's callback. 若是活動的響應項選擇(on-item-selected)的實現沒有處理選擇的項,那麼事件將被傳到碎片的回調.This is true for the Options Menu and context menus.對於選擇菜單和上下文菜單這是真的

For more information about menus, see the Menus and Action Bar developer guides.關於菜單的詳細狀況,請看MenusAction Bar(動做條)開發指南

Handling the Fragment Lifecycle處理碎片的生命週期

Figure 3. The activity lifecycle's affect on the fragment lifecycle.圖3是活動的生命週期對關於碎片的影響

Managing the lifecycle of a fragment is a lot like managing the lifecycle of an activity. Like an activity, a fragment can exist in three states:管理碎片的生命週期,很像管理活動的生命週期,就像活動同樣,一個碎片能夠存在下面三種狀態

Resumed恢復
The fragment is visible in the running activity. 碎片對於動行的活動可見
Paused暫停
Another activity is in the foreground and has focus, but the activity in which this fragment lives is still visible (the foreground activity is partially transparent or doesn't cover the entire screen). 另外一個活動在前臺而且捅有聚焦,可是捅有該碎片的那個活動仍可見(那個前臺的活動部分透明,或者沒有徹底覆蓋整個屏幕)
Stopped中止
The fragment is not visible. Either the host activity has been stopped or the fragment has been removed from the activity but added to the back stack. 碎片不可見,要麼宿主活動已經中止,或者碎片被從活動移除,但加入到了返回堆。A stopped fragment is still alive (all state and member information is retained by the system).一箇中止的碎片仍有生命(全部的成員和信息被系統駐留) However, it is no longer visible to the user and will be killed if the activity is killed. 但,它再也不對用戶可見,而且若是活動被殺掉它也將一併被殺掉.

Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated. 像活動同樣,你也能夠用來Bundle記住碎片的狀態,在活動的進程被殺掉後,當再次從新建立活動時,你須要恢復碎片的狀態。You can save the state during the fragment's onSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), or onActivityCreated().你能夠在碎片的onSaveInstanceState()回調方法中保存狀態,並可在這onCreate(), onCreateView(), 或onActivityCreated幾個方法中恢復它 For more information about saving state, see the Activities document.更多關於保存狀態的信息,請看Activities文檔

The most significant difference in lifecycle between an activity and a fragment is how one is stored in its respective back stack. 在活動與碎片的生命週期之間的最大不一樣之處是,它們存儲在各自相對應的堆中。An activity is placed into a back stack of activities that's managed by the system when it's stopped, by default (so that the user can navigate back to it with the BACK key, as discussed in Tasks and Back Stack)默認狀況下,當活動中止時,它被存放在由系統管理的活動返回堆中(因此用戶能夠用BACK鍵導航返回它,就像Tasks and Back Stack中所討論的). However, a fragment is placed into a back stack managed by the host activity only when you explicitly request that the instance be saved by calling addToBackStack() during a transaction that removes the fragment然而,一個碎片保存在該碎片的宿主活動所管理的返回堆中,僅當在轉換中移除一個碎片時,你顯式的調用了addToBackStack()保存一個實例的請求的狀況下才發生,.

Otherwise, managing the fragment lifecycle is very similar to managing the activity lifecycle. 除此之外,碎片的生命週期的管理很是相似於活動的生命週期So, the same practices for managing the activity lifecycle also apply to fragments.因此活動生命週期的管理的練習一樣適用於碎片。 What you also need to understand, though, is how the life of the activity affects the life of the fragment.雖然如此,但你也須要知道,活動的生命週期是如何影響碎片的生命週期的.

Coordinating with the activity lifecycle協調活動的生命週期

The lifecycle of the activity in which the fragment lives directly affects the lifecycle of the fragment, such that each lifecycle callback for the activity results in a similar callback for each fragment. 碎片所依賴的活動的生命週期,直接影響碎片的生命週期。正爲如此,對於活動的每一個生命週期的回調都會致使對每一個碎片相似的回調For example, when the activity receives onPause(), each fragment in the activity receives onPause().好比,當一個活動收到一個onPause()方法調用,該活動中的每一個碎片將收到onPause()的調用.

Fragments have a few extra lifecycle callbacks, however, that handle unique interaction with the activity in order to perform actions such as build and destroy the fragment's UI. These additional callback methods are:碎片還有其餘的生命週期回調。那是爲了執行像構建和銷燬碎片的UI動做,所須要與活動之間處理的比較特別的交互.這些另外回調方法是

onAttach()
Called when the fragment has been associated with the activity (the Activity is passed in here). 當碎片已經關聯到活動時,補調用( Activity活動被傳到這個方法)
onCreateView()
Called to create the view hierarchy associated with the fragment. 建立與碎片相關的視圖層次時,調用
onActivityCreated()
Called when the activity's onCreate() method has returned. 當活動 onCreate()方法已經返回時,調用.
onDestroyView()
Called when the view hierarchy associated with the fragment is being removed. 當與碎片相關的視圖層次被移除時,調用.
onDetach()
Called when the fragment is being disassociated from the activity. 當碎片從活動中解除關聯時,調用

The flow of a fragment's lifecycle, as it is affected by its host activity, is illustrated by figure 3.圖3說明了碎片的生命週期,就像它的宿主活動所影響的同樣。 In this figure, you can see how each successive state of the activity determines which callback methods a fragment may receive. 在這個圖中,你能夠看到活動的每一個正常的(succesive)狀態,怎麼決定碎片可能收到的回調方法的。For example, when the activity has received its onCreate() callback, a fragment in the activity receives no more than the onActivityCreated() callback.好比,當該活動已收到它的onCreate()方法,該活動中的一個碎片將不僅收到onActivityCreated()回調方法.(意思是,它還會收到其餘方法)

Once the activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, only while the activity is in the resumed state can the lifecycle of a fragment change independently.一旦活動到了恢復狀態,你就能夠自由的往活動加入和移除碎了。所以,只有當活動處在恢復狀態,碎片的生命週期才能獨立的改變.

However, when the activity leaves the resumed state, the fragment again is pushed through its lifecycle by the activity.然而,當活動離開恢復狀態,碎片將再次被活動扔掉它的生命週期.

Example好比

To bring everything discussed in this document together, here's an example of an activity using two fragments to create a two-pane layout.爲了把本文檔全部的討論集中到一塊兒,這裏的這個活動的例子使用兩個碎片建立兩面佈局. The activity below includes one fragment to show a list of Shakespeare play titles and another to show a summary of the play when selected from the list.下面的這個活動,包含一個用於顯示莎士比亞話劇標題列表的碎片,另外一個用於當從列表中選擇時,顯示話劇的摘要。 It also demonstrates how to provide different configurations of the fragments, based on the screen configuration.該例子也演示了對於不一樣屏的配置,相應的提供不一樣的碎片配置。

Note: The complete source code for this activity is available in FragmentLayout.java.注意,這個例子的完整的代碼在FragmentLayout.java這裏.

The main activity applies a layout in the usual way, during onCreate():像平時同樣,主活動在onCreate()中應用一個佈局:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.fragment_layout);
}

The layout applied is fragment_layout.xml://該佈局是一個fragment_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>

Using this layout, the system instantiates the TitlesFragment (which lists the play titles) as soon as the activity loads the layout, while the FrameLayout (where the fragment for showing the play summary will go) consumes space on the right side of the screen, but remains empty at first. 使用這個佈局,當活動裝載佈局時,系統將盡快實例化標題碎片(TitlesFragment ),(它用於列出標題),同時幀佈局FrameLayout(碎片將在這塊空間顯示摘要)將佔用屏幕右邊的空間,但開始這裏還是空的.。As you'll see below, it's not until the user selects an item from the list that a fragment is placed into the FrameLayout.你像你下面所看到的,直到用戶從列表中選中一個時,碎片將被放到幀佈局中FrameLayout.

However, not all screen configurations are wide enough to show both the list of plays and the summary, side by side. 然而,並非全部的屏幕的寬度都足夠同時,一邊顯示話劇標題,一邊顯示摘要So, the layout above is used only for the landscape screen configuration, by saving it at res/layout-land/fragment_layout.xml.因此,上面的佈局只適用於橫向配置的屏幕,經過保存到res/layout-land/fragment_layout.xml中.

Thus, when the screen is in portrait orientation, the system applies the following layout, which is saved at res/layout/fragment_layout.xml:所以,當屏幕是豎向時,系統應用下面這個佈局,該佈局保存在res/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>

This layout includes only TitlesFragment. 這個佈局只包括標題碎片TitlesFragment。This means that, when the device is in portrait orientation, only the list of play titles is visible. 這裏的意思就是說,當設備是豎向時,只能看到話劇的標題表表。So, when the user clicks a list item in this configuration, the application will start a new activity to show the summary, instead of loading a second fragment.因此,當用戶點擊此配置的列表項時,應用將啓動一個新的活動來顯示摘要,而不是裝入第二個碎片。

Next, you can see how this is accomplished in the fragment classes. 接下來,你將能看到碎片是如何完成這些的。First is TitlesFragment, which shows the list of Shakespeare play titles. 首先是標題列表碎片TitlesFragment,它顯示莎士比亞的話劇標題列表.This fragment extends ListFragment and relies on it to handle most of the list view work.這個碎片繼承ListFragment類,而且依賴該類處理大多數列表視圖工做。

As you inspect this code, notice that there are two possible behaviors when the user clicks a list item: 當你觀察這段代碼時,注意當用戶點擊列表項時,有兩種可能的行爲:depending on which of the two layouts is active, 主要處決於兩個佈局的那一個佈局被激活,it can either create and display a new fragment to show the details in the same activity (adding the fragment to the FrameLayout), or start a new activity (where the fragment can be shown).它要麼是在同一個活動中建立一個顯示摘要的一個新碎片,要麼時開啓一個新的活動(碎片將在在新的活動中顯示)

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);
        }
    }
}

The second fragment, DetailsFragment shows the play summary for the item selected from the list from TitlesFragment:第二個碎片,顯示從標題列表中選中的項的摘要:

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;
    }
}

Recall from the TitlesFragment class, that, if the user clicks a list item and the current layout does not include the R.id.details view (which is where the DetailsFragment belongs), then the application starts the DetailsActivity activity to display the content of the item.若是用戶點一個列表項,而且當前佈局沒有包括R.id.details 視圖,TitlesFragment 類將再次調用,而後應用將開啓一個新的DetailsActivity 活動來顯示該項的詳細內容

Here is the DetailsActivity, which simply embeds the DetailsFragment to display the selected play summary when the screen is in portrait orientation:當屏幕是豎向時,這個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();
        }
    }
}

Notice that this activity finishes itself if the configuration is landscape, so that the main activity can take over and display the DetailsFragment alongside the TitlesFragment.注意,若是配置是橫向的這個活動結束它本身,因此主活動能接管而且顯示DetailsFragment 詳細碎片在TitlesFragment標題碎片旁邊。 This can happen if the user begins the DetailsActivity while in portrait orientation, but then rotates to landscape (which restarts the current activity).這種狀況發生在,當是豎向時,用戶開始DetailsActivity 詳細碎片,而後,又轉向到了橫向(這將會重啓當前活動)

For more samples using fragments (and complete source files for this example), see the sample code available in ApiDemos (available for download from the Samples SDK component).使用碎片的更多例子(及這個例子的完整的代碼),看例子代碼在ApiDemos中(從下載的Samples SDK component可用.)

相關文章
相關標籤/搜索