編輯:關於Android編程
Design Philosophy設計理念
Creating a Fragment創建一個Fragment
Adding a user interface 添加一個用戶接口
Adding a fragment to an activity給Activity添加一個Fragment
Managing Fragments 管理Fragment
Performing Fragment Transactions執行Fragment事務
Communicating with the Activity 與Activity進行通訊
Creating event callbacks to the activity給Activity創建事件回調
Adding items to the Action Bar 給ActionBar添加選項
Handling the Fragment Lifecycle 處理Fragment的生命周期
Coordinating with the activity lifecycle 與Activity生命周期的協調
Example
Fragment
FragmentManager
FragmentTransaction
Building a Dynamic UI with Fragments 創建動態的Fragment界面
Supporting Tablets and Handsets 支持平板和手持設備
AFragment
represents a behavior or a portion of user interface in anActivity
. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. 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).
一個Fragment代表了一個行為或在一個Activity用戶界面的一部分。你可以在一個Activity中組合多個Fragment,來構建一個多窗格UI,或重用一個Fragment在多個Activity中。你可以想象Fragment作為一個Activity的一塊,它有自己的生命周期,收到自己的輸入事件,當Activity運行時您可以添加或刪除Fragmen(有點像一個“子的Activity”,您可以重用在不同的Activity中)。
A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle. For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments. However, while an activity is running (it is in theresumedlifecycle 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. The back stack allows the user to reverse a fragment transaction (navigate backwards), by pressing theBackbutton.
一個Fragment必須嵌入在Activity中,它的生命周期直接受主Acitity的生命周期的影響。例如,當Activity暫停,Fragment也暫停,當Activity被銷毀,Fragment也銷毀。然而,當一個Activity在運行的時候(在恢復生命周期狀態),可以獨立操作每個Fragment,例如添加或刪除它們。當您操作一個Fragment將其添加到回退棧中被Activity管理--每一個Activity的回退棧是Fragment發生變化的記錄。按後退按鈕,回堆棧允許用戶改變fragment事務(向後導航)。
When you add a fragment as a part of your activity layout, it lives in aViewGroup
inside the activity's view hierarchy and the fragment defines its own view layout. You can insert a fragment into your activity layout by declaring the fragment in the activity's layout file, as a
element, or from your application code by adding it to an existingViewGroup
. 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.
當你添加一個fragment作為你的Activity布局的一部分的時候,它存在於Activity視圖層的一個ViewGroup中,這個fragment定義了自己的視圖。你可以插入一個fragment布局到你的Activity中,通過在Activity的布局文件中聲明的Fragment,插入
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.
本文檔描述如何使用Fragment構建您的應用程序,包括如何把Fragment添加到Activity的回退棧的時候,保存他們的狀態。Fragment與Activity分享事件,為action bar做出的貢獻或更多。
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. Because a tablet's screen is much larger than that of a handset, there's more room to combine and interchange UI components. 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.
Android介紹fragment在Android3.0(API級別11),主要是為了支持更多的動態和靈活的UI設計的大屏幕上,如平板電腦。因為平板電腦的屏幕比手機更大,有更多的空間組合和交換UI組件。Fragment讓這種設計不需要您來管理復雜的視圖層次的變化。把一個Activity分成Fragment的布局,你可以在運行時修改Activity的外觀和在Activity中的回退棧中管理這些Fragment的變化。
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.
例如,一個新聞應用程序可以使用一個Fragment在左側顯示的文章列表,另一個Fragment在右側顯示一篇文章。每個Fragment都有自己的生命周期回調方法和處理自己的用戶輸入事件。因此,不是使用一個Activity來選擇一篇文章,另一個Activity來讀這篇文章,用戶可以選擇一篇文章和讀它在相同的Acitvity中,如在平板電腦布局如圖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.
你應該設計每個Fragment作為模塊化和可重用的Activity組件。,因為每個Fragment定義了它自己的布局和自身行為有自己的生命周期回調,也可以包括一個Fragment在多個Activity中,所以你應該設計重用,避免直接操縱一個Fragment來自另一個Fragment。這一點尤其重要,因為一個模塊化的Fragment讓你改變你的Fragment組合不同的屏幕尺寸。在設計應用程序時,同時支持平板電腦和手機,你可以重用Fragment在不同布局配置優化用戶體驗基於可用的屏幕空間。例如,手機,它可能需要單獨的Fragment提供UI,當不止一個fragment適應在相同的Activity中。
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.
在一個Activity中Fragment如何定義兩個UI模塊,但是手持設備將分開
For example—to continue with the news application example—the application can embed two fragments inActivity A, when running on a tablet-sized device. However, on a handset-sized screen, there's not enough room for both fragments, soActivity Aincludes only the fragment for the list of articles, and when the user selects an article, it startsActivity B, which includes the second fragment to read the article. Thus, the application supports both tablets and handsets by reusing fragments in different combinations, as illustrated in figure 1.
繼續以上面的新聞為例,當在平板大小的設備上運行的時候,這個應用可以在Activity中嵌入兩個Fragment.然而,在手持設備上的時候,由於沒有足夠的空間盛放這兩個fragment,所以ActivityA只顯示了其中的一個Fragment(新聞列表),當用戶選擇新聞標題的時候,他跳轉到ActvityB,ActivityB中顯示第二個Fragment(新聞詳細信息).那麼通過復用不同組合的Fragment這個應用就可以同時支持平板和手持設備了,如圖1.
For more information about designing your application with different fragment combinations for different screen configurations, see the guide toSupporting Tablets and Handsets.
更多關於使用不同的Fragment組合來設計適應不同屏幕應用的信息,請參閱Supporting Tablets and Handsets一章.
Figure 2.The lifecycle of a fragment (while its activity is running).
To create a fragment, you must create a subclass ofFragment
(or an existing subclass of it). TheFragment
class has code that looks a lot like anActivity
. It contains callback methods similar to an activity, such asonCreate()
,onStart()
,onPause()
, andonStop()
. 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().實際上,如果你在使用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暫停(pause),停止(stop)然後恢復(resume)時,你應該初始化你想要保持的,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 aView
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繪制界面,你必須從這個方法中返回一個View,這個View是你fragment布局的基礎.如果這個Fragment不提供UI,你可以返回空.
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 in more detail in the section aboutHandling the Fragment Lifecycle.
大多數應用至少需要對碎片實現這三個方法,但你也可以使用其他的反饋方式來控制片段生存周期的不同階段。想獲取更多有關生命周期回調方法的詳細信息,請參照Handling the Fragment Lifecycle部分。
There are also a few subclasses that you might want to extend, instead of the baseFragment
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 theActivity
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.
顯示一個浮動的對話框.使用這個類來創建一個對話框是和使用對話Helper方法在Activity類中創建對話框都是很好的方法,因為你可以把Fragment對話框包含在activity管理的Fragment返回棧中,允許用戶返回到關閉的Fragment中.
ListFragment
Displays a list of items that are managed by an adapter (such as aSimpleCursorAdapter
), similar toListActivity
. It provides several methods for managing a list view, such as theonListItemClick()
callback to handle click events.
展示一列被adapter(比如SimpleCursorAdapter)管理的項,和ListActivity很相似.它提供了一些管理一個列表視圖的方法,比如處理點擊事件的onListItemClick()方法.
PreferenceFragment
Displays a hierarchy ofPreference
objects as a list, similar toPreferenceActivity
. This is useful when creating a "settings" activity for your application.
用一個列表來顯示一組偏好設置對象,類似於PreferenceActivity. 在創建設置型的activity時會用到.
A fragment is usually used as part of an activity's user interface and contributes its own layout to the activity.
一個Fragment經常被用作activity界面的一部分,為activity貢獻自己的界面.
To provide a layout for a fragment, you must implement theonCreateView()
callback method, which the Android system calls when it's time for the fragment to draw its layout. Your implementation of this method must return aView
that is the root of your fragment's layout.
為了給fragment提供一個布局,你必須實現onCreateView()方法,Android系統在Fragment繪制他的界面的時候調用這個方法.你對這個方法的實現必須返回一個View,這個View是你Fragment布局的基礎.
Note:If your fragment is a subclass ofListFragment
, the default implementation returns aListView
fromonCreateView()
, so you don't need to implement it.
注意:如果你的Fragment是一個ListFragment類的子類,默認會從onCreateView()返回一個Listview,所以你不需要實現它
To return a layout fromonCreateView()
, you can inflate it from alayout resourcedefined in XML. To help you do so,onCreateView()
provides aLayoutInflater
object.
為了從onCreateView()方法返回一個布局,你可以用一個xml布局文件來填充它.為了幫助你做這個事情,onCreateView() 方法提供了一個LayoutInflater對象.
For example, here's a subclass ofFragment
that loads a layout from theexample_fragment.xml
file:
比如,這個一個Fragment的子類,它是從example_fragment.xml文件載入的布局:
publicstaticclassExampleFragmentextendsFragment{ @Override publicView onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState){ // Inflate the layout for this fragment return inflater.inflate(R.layout.example_fragment, container,false); } }
In the sample above,R.layout.example_fragment
is a reference to a layout resource namedexample_fragment.xml
saved in the application resources. For information about how to create a layout in XML, see theUser Interfacedocumentation.
和上面差不多,R.layout.example_fragment是在系統保存的example_fragment.xml這個布局資源的引用.更多關於使用一個xml文件創建一個布局的信息,參考User Interface 文檔.
Thecontainer
parameter passed toonCreateView()
is the parentViewGroup
(from the activity's layout) in which your fragment layout will be inserted. ThesavedInstanceState
parameter is aBundle
that provides data about the previous instance of the fragment, if the fragment is being resumed (restoring state is discussed more in the section aboutHandling the Fragment Lifecycle).
傳遞給onCreateView()的容器參數是,fragment插入的activity的父ViewGroup(來自對應的activity布局).savedInstanceState的參數是一個提供關於之前Fragment狀態數據的Bundle,如果這個Fragment被恢復了 (resume,恢復數據在處理Fragment生命周期這一節有更多介紹)
Theinflate()
method takes three arguments:
inflate()方法接收三個參數:
The resource ID of the layout you want to inflate.
你想要添加的布局資源ID.
TheViewGroup
to be the parent of the inflated layout. Passing thecontainer
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.
將作為填充布局的父容器的ViewGroup.傳遞容器參數是非常重要的,只用這樣才能使系統應用布局參數到填充視圖的根視圖,從而被它的父視圖所確定
A boolean indicating whether the inflated layout should be attached to theViewGroup
(the second parameter) during inflation. (In this case, this is false because the system is already inserting the inflated layout into thecontainer
—passing true would create a redundant view group in the final layout.)
一個boolean類型的參數,用於在填充時指明填充的布局是否應該附加在ViewGroup(第二個參數)上.(如果系統已經插入這個填充布局到容器了就返回false,如果將要在最終布局中創建一個多余的viewgroup,那就返回true)
Now you've seen how to create a fragment that provides a layout. Next, you need to add the fragment to your 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. There are two ways you can add a fragment to the activity layout:
一般的一個fragment提供了Activity UI的一部分,他作為Activity全局視圖層的一部分而嵌入.有兩種方法可以把fragment嵌入到Activity布局中:
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:
這樣的話,你可以在視圖中指定Fragment的布局屬性,比如,這是一個嵌入兩個Fragmet的Activity:
Theandroid:name
attribute in the
specifies theFragment
class to instantiate in the layout.
When the system creates this activity layout, it instantiates each fragment specified in the layout and calls theonCreateView()
method for each one, to retrieve each fragment's layout. The system inserts theView
returned by the fragment directly in place of the
element.
當系統生成這個activity布局時,會把布局中每個特定的片段實例化,然後依次調用onCreateView()方法以便檢索每個片段布局。系統直接插入片段返回的視圖來代替
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:
在系統創建這個Activity布局的時候,他會實例化每個布局中的每個fragment,調用每個fragment的onCreateView()方法 來取回每個fragment的視圖.系統把fragment返回的視圖直接插入到
Supply theandroid:id
attribute with a unique ID.
使用android:id來指定它唯一的ID.
Supply theandroid:tag
attribute with a unique string.
使用android:tag來指定一個唯一的字符串標志
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 existingViewGroup
.
或以編程方式的把fragment添加到ViewGroup中.
At any time while your activity is running, you can add fragments to your activity layout. You simply need to specify aViewGroup
in which to place the fragment.
在任何你Activity運行的時候,你都可以把fragment添加到Activity的視圖中.你只需要指定一個用於盛放Fragment的 ViewGroup.
To make fragment transactions in your activity (such as add, remove, or replace a fragment), you must use APIs fromFragmentTransaction
. You can get an instance ofFragmentTransaction
from yourActivity
like this:
為了讓fragment可以被管理(比如添加,刪除,替換fragment),你必須使用來自 FragmentTransaction的API.你可以像下面這樣在Activity中獲取一個FragmentTransaction的實例:
FragmentManager fragmentManager =getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
;
You can then add a fragment using theadd()
method, specifying the fragment to add and the view in which to insert it. For example:
你可以使用Add()方法添加一個Fragment,指定要添加的Fragment和目標View,如下:
ExampleFragment fragment =newExampleFragment(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();
The first argument passed toadd()
is theViewGroup
in which the fragment should be placed, specified by resource ID, and the second parameter is the fragment to add.
add()方法中的第一個參數是Fragment所要放置的目標ViewGroup,通過資源ID指定,第二個參數是要添加的Fragment.
Once you've made your changes withFragmentTransaction
, you must callcommit()
for the changes to take effect.
只要你使用FragmentTransaction做了修改,你必須調用commit()方法來使修改生效.
The examples above show how to add a fragment to your activity in order to provide a UI. However, you can also use a fragment to provide a background behavior for the activity without presenting additional UI.
上面的例子想你展示了怎麼添加一個含有UI的Fragment到你的Actvity.然而,對於不想增加而外UI的Activity來說,你也可以使用Fragment來進行後台行為.
To add a fragment without a UI, add the fragment from the activity usingadd(Fragment, String)
(supplying a unique string "tag" for the fragment, rather than a view ID). This adds the fragment, but, because it's not associated with a view in the activity layout, it does not receive a call toonCreateView()
. So you don't need to implement that method.
為了添加一個沒有UI的Fragment.需要使用add(Fragment, String) 方法,其中,你需要為Fragment提供一個字符串的標志而不是一個視圖ID.這樣增加的Fragment,由於沒有涉及到Activity的視圖,所 以不會調用onCreateView()方法.所以你不需要實現這個方法.
Supplying a string tag for the fragment isn't strictly for non-UI fragments—you can also supply string tags to fragments that do have a UI—but if the fragment does not have a UI, then the string tag is the only way to identify it. If you want to get the fragment from the activity later, you need to usefindFragmentByTag()
.
為Fragment提供一個字符串標志不一定只局限於沒有UI的Fragment,你也可以為有UI的Fragment指定一個字符串標志,但是如果這個 Fragment真的沒有UI,那這個字符串標志是確定它的唯一標志.如果你想在後面從Activity中獲取到這個fragment,你需要使用 findFragmentByTag()方法
For an example activity that uses a fragment as a background worker, without a UI, see theFragmentRetainInstance.java
sample.
舉個例子,ativity使用fragment作為一個後台工作者,沒有UI。see theFragmentRetainInstance.java
例子.
To manage the fragments in your activity, you need to useFragmentManager
. To get it, callgetFragmentManager()
from your activity.
為了管理你Activity中的fragment,你需要使用FragmentManager.你可以通過你Activity中的getFragmentManager()來獲取它.
Some things that you can do withFragmentManager
include:
使用FragmentManager你可以做到:
Get fragments that exist in the activity, withfindFragmentById()
(for fragments that provide a UI in the activity layout) orfindFragmentByTag()
(for fragments that do or don't provide a UI).
使用findFragmentById()(提供UI的Fragment)或者findFragmentByTag()(沒有提供UI的Fragment) 獲取你Activity存在的Fragment
Pop fragments off the back stack, withpopBackStack()
(simulating aBackcommand by the user).
使用popBackStack()把Fragment從返回棧中彈出(模擬用戶的返回命令).
Register a listener for changes to the back stack, withaddOnBackStackChangedListener()
.
使用addOnBackStackChangedListener()方法為返回棧的變化注冊監聽器.
For more information about these methods and others, refer to theFragmentManager
class documentation.
請參考文檔的 FragmentManager 類來查看過於這些方法(還有其他方法)的更多內容.
As demonstrated in the previous section, you can also useFragmentManager
to open aFragmentTransaction
, which allows you to perform transactions, such as add and remove fragments.
正如前面的文檔所講的,你也可以使用FragmentManager來打開FragmentTransaction,FragmentTransaction允許你執行添加,刪除Fragment的事務.
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 inFragmentTransaction
. 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).
在你的Activity中使用Fragment的最大好處就是可以針對用戶的操作,進行對Fragment的添加,移除,替換等等其他操作.你提交給 Activity的每個變化稱為一個事務,這些事務你可以使用FragmenTransaction的API來實現.你也可以在Activity管理的返 回棧中保存每個事務,使用戶可以在Fragmen的變化後返回之前的狀態(類似於在Activity跳轉後的返回).
You can acquire an instance ofFragmentTransaction
from theFragmentManager
like this:
你可以像這樣從FragmentManager中取得一個FragmentTransaction的實例:
FragmentManager fragmentManager =getFragmentManager()
; FragmentTransaction fragmentTransaction = fragmentManager.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 asadd()
,remove()
, andreplace()
. Then, to apply the transaction to the activity, you must callcommit()
.
每個事務是一系列你想要同時執行的Fragmen的變化.你可以使用像add(),remove(),replace()這樣的方法來為一個事務設定你想要執行的操作.為了使Activity的事務生效,你必須執行commit()方法.
Before you callcommit()
, however, you might want to calladdToBackStack()
, in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing theBackbutton.
在你調用commit()方法的之前,為了添加這個事務到一個Fragmen事務的返回棧,你可能想要調用addToBackStack()方法.這個返回棧被Activity管理,允許用戶通過按下返回按鍵返回之前的Fragmen狀態.
For example, here's how you can replace one fragment with another, and preserve the previous state in the back stack:
這裡展示了怎麼使用一個Fragmen替換另一個,然後在返回棧中返回到之前的狀態.
// Create new fragment and transaction Fragment newFragment =newExampleFragment(); 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 theR.id.fragment_container
ID. By callingaddToBackStack()
, the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing theBackbutton.
在這個例子中,新的Fragmen替換了R.id.fragment_container ID指定的布局容器中當前存在的fragment(如果存在的話).通過調用addToBackStack()方法,替換事務被保存在了返回棧中,這樣用 戶可以回退這個事務,通過按下返回鍵返回到以前的fragment.
If you add multiple changes to the transaction (such as anotheradd()
orremove()
) and calladdToBackStack()
, then all changes applied before you callcommit()
are added to the back stack as a single transaction and theBackbutton will reverse them all together.
如果你在事務中添加了多個變化(比如另一個add()方法或者remove()方法),然後調用了addToBackStack()方法,那在你調用commit()方法之前的所有變化都會作為單獨的事務被添加到返回棧中,返回鍵將會把他們全部回退.
The order in which you add changes to aFragmentTransaction
doesn't matter, except:
除了下面這些,其他的情況和你在FragmentTransaction中添加的順序沒有關
You must callcommit()
last
你必須在最後調用commit()方法
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
如果你在向同一個容器添加多個fragment,那麼你添加的順序決定了他們在視圖層出現的順序.
If you do not calladdToBackStack()
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. Whereas, if you do calladdToBackStack()
when removing a fragment, then the fragment isstoppedand will be resumed if the user navigates back.
如果在你執行一個移除所有fragment的事務的時候沒有調用addToBackStack()方法,那麼這個fragment將會在事務提交後被摧 毀,用戶不能再返回到之前的fragment.如果你在移除fragment的時候調用了addToBackStack()方法,那這個fragment 會被停止,並可以在用戶按返回的時候恢復.
Tip:For each fragment transaction, you can apply a transition animation, by callingsetTransition()
before you commit.
注意:對於每個fragment事務,你可以在提交之前通過調用setTransition()來應用一個fragment動畫.
Callingcommit()
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. If necessary, however, you may callexecutePendingTransactions()
from your UI thread to immediately execute transactions submitted bycommit()
. Doing so is usually not necessary unless the transaction is a dependency for jobs in other threads.
調用commit()方法不能立即執行事務而是安排它運行在Activity的UI線程中("主"線程)---如果這線程可以這麼做的話.如果需要,你可 以在你UI線程中調用executePendingTransactions()方法來直接執行commit()方法提交的事務.這麼多一般不必要除非事 務依賴於其他線程的工作.
Caution:You can commit a transaction usingcommit()
only prior to the activitysaving its state(when the user leaves the activity). 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, usecommitAllowingStateLoss()
.
注意:你只可以在Activity保存他狀態之前(在用戶離開這個Actvity的時候)使用commit()方法來提交一個事務.如果你在這個時間點之 後提交,系統會拋出一個異常.這是因為如果Activity需要恢復,在提交之後的狀態可能會丟失.對於允許丟失提交的情況,請使用 commitAllowingStateLoss()方法.
Although aFragment
is implemented as an object that's independent from anActivity
and can be used inside multiple activities, a given instance of a fragment is directly tied to the activity that contains it.
即使fragment是作為一個object實現的,獨立於Activity的並且可以在那多個Activity中使用,但是一個fragment實例還是和它所在的容器有直接的關系.
Specifically, the fragment can access theActivity
instance withgetActivity()
and easily perform tasks such as find a view in the activity layout:
特別的,fragment可以通過getActivity()方法來訪問Activity實例並可以輕易的執行像在activity視圖中查找View的任務.
View listView =getActivity()
.findViewById
(R.id.list);
Likewise, your activity can call methods in the fragment by acquiring a reference to theFragment
fromFragmentManager
, usingfindFragmentById()
orfindFragmentByTag()
. For example:
同樣的,使用findFragmentById()或findFragmentByTag()通過從FragmentManager獲取一個對這個Fragment的引用,你的Activity可以調用fragment中的方法
ExampleFragment fragment =(ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
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.
在一些情況下,你可能需要一個Fragment和Activity共享事件.一個好的方法是在Fragment中定義一個回調接口然後讓承載他的Activity實現它.當Activity通過接口接收到調用時,必要時他可以和視圖中的其他Fragment共享信息.
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. In this case, theOnArticleSelectedListener
interface is declared inside fragment A:
舉個例子,如果一個新的應用在一個Activity中有兩個Fragment,一個顯示一列文章標題(FragmentA),另一列顯示文章內容 (FragmentB),那麼在一列被選中的時候,FragmentA必須告訴Actvity那一列被選中了,這樣Actvity就可以告訴 FragmentB顯示哪一篇文章.在這種情況下,OnArticleSelectedListener 接口會在FragmentA中聲明.
publicstaticclassFragmentAextendsListFragment{ ... // Container Activity must implement this interface publicinterfaceOnArticleSelectedListener{ publicvoid onArticleSelected(Uri articleUri); } ... }
Then the activity that hosts the fragment implements theOnArticleSelectedListener
interface and overridesonArticleSelected()
to notify fragment B of the event from fragment A. To ensure that the host activity implements this interface, fragment A'sonAttach()
callback method (which the system calls when adding the fragment to the activity) instantiates an instance ofOnArticleSelectedListener
by casting theActivity
that is passed intoonAttach()
:
然後承載Fragment的Activity實現OnArticleSelectedListener接口並重寫onArticleSelected() 方法來通知FragmentB響應FragmentA的事件.為了保證這個Activity實現了這個接口,FragmentA的onAttach()方 法(系統在添加Fragment到這個Activity的時候調用)通過把Activity參數傳遞到onAttach()方法傳遞實例化一個 OnArticleSelectedListener實例.
publicstaticclassFragmentAextendsListFragment{ OnArticleSelectedListener mListener; ... @Override publicvoid onAttach(Activity activity){ super.onAttach(activity); try{ mListener =(OnArticleSelectedListener) activity; }catch(ClassCastException e){ thrownewClassCastException(activity.toString()+" must implement OnArticleSelectedListener"); } } ... }
If the activity has not implemented the interface, then the fragment throws aClassCastException
. On success, themListener
member holds a reference to activity's implementation ofOnArticleSelectedListener
, so that fragment A can share events with the activity by calling methods defined by theOnArticleSelectedListener
interface. For example, if fragment A is an extension ofListFragment
, each time the user clicks a list item, the system callsonListItemClick()
in the fragment, which then callsonArticleSelected()
to share the event with the activity:
如果Activity沒有實現這個接口,那麼Fragment會拋出ClassCastException異常.上面的成功例子中,mListener成 員有一個Activity實現的OnArticleSelectedListener的引用.這樣FragmentA可以通過調用 OnArticleSelectedListener接口定義的方法來共享事件.比如:如果FragmentA是listFragment的擴展,用戶每 次點擊list的一項,系統會調用Fragment的onListItemClick()方法,然後調用onArticleSelected() 方法來和Activity分享事件信息.
publicstaticclassFragmentAextendsListFragment{
OnArticleSelectedListener mListener;
...
@Override
publicvoid 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);
}
...
}
Theid
parameter passed toonListItemClick()
is the row ID of the clicked item, which the activity (or other fragment) uses to fetch the article from the application'sContentProvider
.
onListItemClick()方法傳遞的參數是點擊項的行ID,Activity(或Fragment)可以用它來從應用的ContentProvider填充文章信息.
More information about using a content provider is available in theContent Providersdocument.
更多關於使用content provider的信息請參閱Content Providers文檔.
Your fragments can contribute menu items to the activity'sOptions Menu(and, consequently, theAction Bar) by implementingonCreateOptionsMenu()
. In order for this method to receive calls, however, you must callsetHasOptionsMenu()
duringonCreate()
, to indicate that the fragment would like to add items to the Options Menu (otherwise, the fragment will not receive a call toonCreateOptionsMenu()
).
你的Fragment可以通過實現onCreateOptionsMenu()來為Activity的Options Menu創建菜單項(結果就是形成ActionBar).為了讓這個方法接收到調用,你必須在onCreate()方法中調用 setHasOptionsMenu()方法來表明這個Fragment允許在Options Menu中增加項(否則,Fragment將不能接收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 toonOptionsItemSelected()
when a menu item is selected.
你從Fragment 添加到 Options Menu的任何項都是現存菜單項的附加項.在一個菜單項選中的時候,Fragment也接收響應onOptionsItemSelected()方法的調用.
You can also register a view in your fragment layout to provide a context menu by callingregisterForContextMenu()
. When the user opens the context menu, the fragment receives a call toonCreateContextMenu()
. When the user selects an item, the fragment receives a call toonContextItemSelected()
.
你也可以在你的Fragment視圖中通過調用registerForContextMenu()方法來注冊一個視圖,從而提供一個上下文菜單.當用戶打 開上下文菜單時,Fragment會接收一個onCreateContextMenu()的調用,當用戶選擇一項的時候,Fragment接收一個 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. 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. This is true for the Options Menu and context menus.
注意.即使你的Fragment在每個添加的菜單項接收了一個on-item-selected調用,在用戶選擇一個菜單項的時候,Activity是第 一個接受各自調用的組件.如果Activity實現的on-item-selected調用沒有處理選擇項後的事件,那這個事件會傳遞到Fragment 的回調中.這對 Options Menu 和上下文菜單都是適用的.
For more information about menus, see theMenusandAction Bardeveloper guides.
更多關於菜單的信息,參考Menus and Action Bar一文.
Figure 3.The effect of the activity lifecycle on the fragment lifecycle.
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:
Fragment的生命周期和處理Activity的生命周期很相似.和Activity一樣,Fragment的生命周期有一下三個狀態:
Resumed
The fragment is visible in the running activity.
Fragment在運行中的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).
另一個Activity在前台或者獲得了焦點,但是Fragment所在的Activity仍然可以看到(可能是前台Activity占據了屏幕的一部分或者是半透明的)
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.
Fragment不可見.宿主Activity可能已經被停止了或者這個Fragment已經從這個Activity中移除了並被添加到了返回棧.一個停 止的Fragment仍然是存活的(所有的狀態和成員信息被系統保存著).然而他不再對Activity可見,如果宿主Activity被殺死了,他也會 被殺死.
Also like an activity, you can retain the state of a fragment using aBundle
, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated. You can save the state during the fragment'sonSaveInstanceState()
callback and restore it during eitheronCreate()
,onCreateView()
, oronActivityCreated()
. For more information about saving state, see theActivitiesdocument.
和Activity一樣,在這個Activity所在的進程被殺死或者你需要在Activity重新創建的時候保存Fragment的狀態,你可以用 Bundle來做這個工作.你可以在Fragment執行onSaveInstanceState()方法的時候保存它的狀態,然後在 onCreate()或者onCreateView(),onActivityCreated()方法的時候恢復這些狀態.更多關於保存狀態的內容參考 Activity文檔.
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 theBackbutton, as discussed inTasks 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 callingaddToBackStack()
during a transaction that removes the fragment.
Activity和Fragment最大的不同是他們在返回棧中的存在形式.默認的,Activity在停止的時候,是放在一個被系統管理的返回棧中(這 樣用戶可以使用back按鈕返回,就像在Tasks and Back Stack一章中談論的那樣).然而在一個移除Fragment的事務中,只有在你通過調用addToBackStack()明確的指明這個 Fragment不要被保存,這個Fragment才會被放在被宿主Activity管理的返回棧中.
Otherwise, managing the fragment lifecycle is very similar to managing the activity lifecycle. So, the same practices formanaging the activity lifecyclealso apply to fragments. What you also need to understand, though, is how the life of the activity affects the life of the fragment.
另外,管理Fragment的生命周期和管理Activity的生命周期很相似.所以,當管理Activity生命周期的方法也適於管理Fragment的生命周期.當然你也需要明確Activity對Fragment生命周期的影響.
Caution:If you need aContext
object within yourFragment
, you can callgetActivity()
. However, be careful to callgetActivity()
only when the fragment is attached to an activity. When the fragment is not yet attached, or was detached during the end of its lifecycle,getActivity()
will return null.
注意,如果在你的Fragment中需要一個context對象,你可以調用getActivity.然而,只有這個Fragment附在這個 Activity上的時候,才可以調用getActivity().如果Fragment還沒有附加在Activity上,或者在最後的生命周期和 Activity分離了,那getActivity()方法將會返回null.
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 receivesonPause()
, each fragment in the activity receivesonPause()
.
擁有Fragment的Activity的生命周期會直接影響Fragment的生命周期,每個Activity生命周期方法會影響到每個 Fragment.舉個例子,當一個Activity執行onPause()方法的時候,它裡面的每個Fragment也會執行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:
Fragment有一些額外的生命周期,用來處理和Activity的特殊交換,從而可以執行形如創建和銷毀FragmentUI的事情.這些額外的回調方法有:
onAttach()
Called when the fragment has been associated with the activity (theActivity
is passed in here).
當Fragment和Activity鏈接起來的時候調用(Activity在這裡傳送過來).
onCreateView()
Called to create the view hierarchy associated with the fragment.
創建Fragment的視圖層.
onActivityCreated()
Called when the activity'sonCreate()
method has returned.
當Activity的onCreate返回的時候執行.
onDestroyView()
Called when the view hierarchy associated with the fragment is being removed.
當Fragment的試圖層被移除的時候執行.
onDetach()
Called when the fragment is being disassociated from the activity.
當Fragment和Activity分離的時候執行.
The flow of a fragment's lifecycle, as it is affected by its host activity, is illustrated by figure 3. In this figure, you can see how each successive state of the activity determines which callback methods a fragment may receive. For example, when the activity has received itsonCreate()
callback, a fragment in the activity receives no more than theonActivityCreated()
callback.
Fragment生命周期的流圖,由於被宿主Activity影響,可以用圖三表示.在這個表中,你可以知道每個Activity的每個狀態是怎樣決定一 個Fragment收到的回調方法的.比如,當一個Activity收到他的onCreate()方法的時候,他裡嗎的Fragment不會再收到 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.
一旦Activity到達了resume狀態,你可以隨意添加和移除Activity中的Fragment.當然,只有這個Activity在resume狀態的時候,Fragment的生命周期才可以獨立的變化.
However, when the activity leaves the resumed state, the fragment again is pushed through its lifecycle by the activity.
然而,當activity離開了resume狀態,Fragment會再一次被activity推到它的生命周期中.
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.
為了把上面介紹的知識匯總,這裡有個使用兩個Fragment組成兩個視圖布局的例子.下面的activity包含兩個Fragment,一個用來顯示 Shakespeare話劇的標題,另一個用來顯示選中話劇的簡介.也演示了怎麼根據屏幕的不同為這兩個Fragment提供不同的配置.
Note:The complete source code for this activity is available inFragmentLayout.java
.
注意:完整代碼在FragmentLayout.java中.
The main activity applies a layout in the usual way, duringonCreate()
:
主activity用平常的方式生成布局,在onCreate()方法的時候:
@Override protectedvoid onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.fragment_layout); }
The layout applied isfragment_layout.xml
:
Using this layout, the system instantiates theTitlesFragment
(which lists the play titles) as soon as the activity loads the layout, while theFrameLayout
(where the fragment for showing the play summary will go) consumes space on the right side of the screen, but remains empty at first. As you'll see below, it's not until the user selects an item from the list that a fragment is placed into theFrameLayout
.
通過布局文件我們知道,系統在activity載入布局的時候實例化TitlesFragment(話劇的標題),FragmentLLayout(顯示 話劇內容簡介的Fragment)占據右邊的屏幕但是現在沒有內容.就像你下面看到的那樣,直到用戶選擇了標題一個Fragment才會被放到 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 atres/layout-land/fragment_layout.xml
.
然而,不是多有的屏幕配置都足夠顯示這兩個Fragment視圖.按照res/layout-land/fragment_layout.xml文件,上面的布局只適合橫屏.
Thus, when the screen is in portrait orientation, the system applies the following layout, which is saved atres/layout/fragment_layout.xml
:
那麼當屏幕在豎屏的時候,系統會使用下面的布局,保存在res/layout/fragment_layout.xml中
This layout includes onlyTitlesFragment
. 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.
這個布局值包含TitlesFragment.這意味著當設備在豎屏的時候,只有話劇的標題是可見的.所以,當用戶點擊列表的一項的時候,應用將會開始一個新的activity來顯示簡介而不是載入第二個Fragment.
Next, you can see how this is accomplished in the fragment classes. First isTitlesFragment
, which shows the list of Shakespeare play titles. This fragment extendsListFragment
and relies on it to handle most of the list view work.
接下來,你將看到這在Fragment類中是怎麼實現的.首先是TitleFragment,顯示了莎士比亞話劇的標題.這個Fragment繼承自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 theFrameLayout
), or start a new activity (where the fragment can be shown).
正如你看到的那樣,注意在用戶點擊列表響的時候,有兩個可能的行為:如果這兩個視圖存在,將在這個activity中創建並顯示一個新的 Fragment(把Fragment添加到FragmentLayout中);如果只有一個視圖(豎屏),那會啟動一個新的 activity(Fragment在這個activity中顯示).
publicstaticclassTitlesFragmentextendsListFragment{ boolean mDualPane; int mCurCheckPosition =0; @Override publicvoid onActivityCreated(Bundle savedInstanceState){ super.onActivityCreated(savedInstanceState); // Populate list with our static array of titles. setListAdapter(newArrayAdapter(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 publicvoid onSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition); } @Override 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){ // 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(); if(index ==0){ ft.replace(R.id.details, details); }else{ ft.replace(R.id.a_item, 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 =newIntent(); 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 fromTitlesFragment
:
第二個Fragment,DetailsFragment顯示了在TitleFragment中選中的話劇簡介.
publicstaticclassDetailsFragmentextendsFragment{ /** * Create a new instance of DetailsFragment, initialized to * show the text at '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; } }
Recall from theTitlesFragment
class, that, if the user clicks a list item and the current layout doesnotinclude theR.id.details
view (which is where theDetailsFragment
belongs), then the application starts theDetailsActivity
activity to display the content of the item.
來自TitleFragment的調用,如果用戶點擊列表項的時候當前布局不包含R.id.details視圖(DetailsFragment 所在的視圖),那應用將會啟動DetailsActivity 來顯示選中項的內容簡介.
Here is theDetailsActivity
, which simply embeds theDetailsFragment
to display the selected play summary when the screen is in portrait orientation:
這裡是DetailsActivity,在屏幕是豎屏的時候,簡單的嵌入在了Fragment中來顯示選中的話劇簡介.
publicstaticclassDetailsActivityextendsActivity{ @Override protectedvoid 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 =newDetailsFragment(); 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 theDetailsFragment
alongside theTitlesFragment
. This can happen if the user begins theDetailsActivity
while in portrait orientation, but then rotates to landscape (which restarts the current activity).
注意activity會在橫屏的時候結束自己,這樣主activity可以接管並顯示DetailsFragment旁邊的TitlesFragment.如果用戶在豎屏的時候啟動DetailsActivity,然後把設備轉到橫屏(將會重啟當前的activity).
For more samples using fragments (and complete source files for this example), see the API Demos sample app available inApiDemos
(available for download from theSamples SDK component).
更多使用Fragment的例子(包括這個例子的全部代碼),請參考API Demo(可以在SDK例子那裡下載).
RecyclerView 是 android-support-v7-21 版本中新增的一個 Widgets。我們可以使用RecyclerView非常簡單的實現橫向豎向的L
廣播是一種廣泛運用在應用程序之間傳輸信息的機制,android中的廣播用於監聽系統事件或應用程序事件!android中的廣播包括普通廣播、有序廣播以及異步廣播(粘性廣播)
魅族發布了今年最後一款歷史性新品---魅藍metal,魅藍metal依舊采用了與或卡托(單卡槽雙卡位)設計,且支持雙卡雙待,目前預約的有移動定制版和公開版。
在Android應用開發中會經常碰到一個叫divider的東西,就是兩個View之間的分割線。最近工作中注意到這個divider並分析了一下,竟然發現內有乾坤,驚為天人…