由于本人英文能力實在有限,不足之初敬請諒解
本博客只要沒有注明“轉”,那么均為原創,轉貼請注明鏈接
?
本系列并沒有對原文100%翻譯,也沒有100%的貼出原文
?
Fragment也是android3.0(api level 11)新增的組件
public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener
已知的直接子類有
DialogFragment, ListFragment, PreferenceFragment, WebViewFragment
?
Fragment緊密的綁定到它所在的Activity中,并且不能脫離其使用
盡管Fragment定義了它自己的聲明周期,它也是依賴于它的activity的
如果activity?is stopped,activity里面的fragments都不會被start,當activity?is destroyed,所有的fragments也將destroyed
A Fragment is closely tied to the Activity it is in, and can not be used apart from one. Though Fragment defines its own lifecycle, that lifecycle is dependent on its activity: if the activity is stopped, no fragments inside of it can be started; when the activity is destroyed, all fragments will be destroyed
?
Fragment的所有子類必須包含一個public?empty構造函數
當需要的時候,特別是在恢復state期間,framework會經常重新實例化一個fragment類,并且需要能找到這個構造器去實例化它
如果empty構造函數不可用,在一些恢復state的情況下會出現運行時異常
All subclasses of Fragment must include a public empty constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it. If the empty constructor is not available, a runtime exception will occur in some cases during state restore
?
?
從下邊的圖可以很清晰的看出fragment的生命周期
如果fragment在頁面上有需要顯示的部分,那么必須重寫onCreateView(),并且返回一個View(fragment的layout的root)
如果沒有需要顯示的,當然也就不用理睬這個函數了
如果繼承的是ListFargment,那么也不用重寫onCreateView(),ListFargment已經重寫過了
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); } }
?
添加fragment到activity中(兩種方式)
a.在activity的layout中聲明,可以為fragment像View一樣指定layout屬性
<?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>
android:name指定了實例化fragment所用到的類
?
?
b.在程序中添加fragment到ViewGroup
在你的activity運行的任何時候,你都可以添加fragment到你的activity的布局中,你只需指定一個ViewGroup來放置fragment即可
下面演示fragment的事務處理
FragmentManager fragmentManager = getFragmentManager() FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); ExampleFragment fragment = new ExampleFragment(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();
? 一旦使用FragmentTransaction改變了fragment,那么必須調用commit來是它生效
?
每個fragment都需要一個唯一標識,有三種方法指定唯一標識
1.android:id
2.android:tag
3.如果沒有提供上面兩個中任何一個,系統則使用他container view的ID作為標識
?
添加一個沒有UI的fragment
在activity中使用add(Fragment, String)這樣(使用一個唯一string的tag要比一個view id好)添加一個不帶UI的fragment。這樣可以添加fragment,但是因為它并沒有與activity中layout的View關聯,所以它不會收到onCreateView()的調用,所以也不需要實現這個方法。
為fragment提供一個字符串tag,并不嚴格局限于沒有UI的fragment,你可以為帶有UI的fragment提供一個字符串tag,但是如果fragment沒有UI,那么字符串tag是唯一標識它的方式。如果之后你想從activity獲得此fragment,你需要使用findFragmentByTag()
?
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). 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.
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 use findFragmentByTag().
?
?
一個沒有UI的fragment例子(之后的blog中會有api demos關于fragment的學習)
ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
?
管理fragment可以通過FragmentManager
在activity中可以通過getFragmentManager()獲得FragmentManager
執行fragment事務可以通過FragmentTransaction
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
事務是你提交到activity的一個改變的集合,可以用FragmentTransaction中的api來執行
你也可以save每一個transaction到一個由activity管理的back stack中,允許用戶向后導航fragment的改變(類似于向后導航activities)
?
在調用commit()之前,可是你也許想要調用addToBackStack(),把transaction添加到fragment的事務集的一個的back stack中
這個back stack是由activity管理的,并且允許用戶按返回鍵返回到上一個fragment狀態
?
一個例子演示了如何用一個fragment替換另一個fragment,并且在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();
這個例子中,newFragment替換了當前在layout容器中通過ID:R.id.fragment_container標識的fragment
調用addToBackStack(),這個“替換”事務被保存到back stack中,所以用戶可以回退這個事務并且通過按back鍵把上一個fragment帶回來
?
?
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 button will reverse them all together.
如果你添加多項改變到事務中(例如另一個add或者remove)并且調用addToBackStack(),
那么在你調用commit()之前,所有被實施的改變作為一個單一的事務添加到back stack,Back鍵將會把他們一起回退
?
這里說一下順序的問題
順序并不在重要, 但是:
必須在最后調用commit()
如果在同一個container中添加了多個fragments,添加的順序決定了他們在view層級中顯示的順序
?
如果你在執行一個移除fragment操作的事務時不調用addToBackStack()。那么當這個transaction被提交后fragment會被銷毀,并且用戶不可能回退回去。
相反,如果當移除fragment時,你調用addToBackStack(),那么這個fragment會stopped,并且如果用戶導航回去它會resumed
小提示:對于每一個fragment的事務,在commit()之前通過調用setTransition(),你可以使用一個過渡動畫
?
調用commit()并不是馬上就執行這次事務,恰恰相反,一旦activity的UI線程有能力去完成,FragmentTransaction就把這次提交列入計劃到activity的UI線程運行
?
如果必要,不管怎樣,你可以從你的UI線程調用executePendingTransactions()來通過commit()立即執行提交了的transaction。通常這樣做并不是必須的,除非transaction是其他線程工作的依賴
警告:只有在activity之前(當用戶離開這個activity時)你可以用commit()提交一個transaction保存他的狀態
如果你嘗試在這個時間點之后commit,將會收到一個異常。這是因為如果activity需要恢復,在commit之后的state可能會丟失。在你覺得可以丟失這次commit的情況下,可以使用commitAllowingStateLoss()
?
?
絕大部分來自對下面地址的翻譯,英文水平實在有限,希望拍磚同時能給予指正。
http://developer.android.com/guide/topics/fundamentals/fragments.html
?
?
轉貼請保留以下鏈接
本人blog地址
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
