由于本人英文能力實(shí)在有限,不足之初敬請(qǐng)諒解
本博客只要沒有注明“轉(zhuǎn)”,那么均為原創(chuàng),轉(zhuǎn)貼請(qǐng)注明鏈接
?
android Fragment開發(fā)文檔翻譯 - 1
android Fragment開發(fā)文檔翻譯 - 2
本系列并沒有對(duì)原文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都不會(huì)被start,當(dāng)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的所有子類必須包含一個(gè)public?empty構(gòu)造函數(shù)
當(dāng)需要的時(shí)候,特別是在恢復(fù)state期間,framework會(huì)經(jīng)常重新實(shí)例化一個(gè)fragment類,并且需要能找到這個(gè)構(gòu)造器去實(shí)例化它
如果empty構(gòu)造函數(shù)不可用,在一些恢復(fù)state的情況下會(huì)出現(xiàn)運(yùn)行時(shí)異常
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(),并且返回一個(gè)View(fragment的layout的root)
如果沒有需要顯示的,當(dāng)然也就不用理睬這個(gè)函數(shù)了
如果繼承的是ListFargment,那么也不用重寫onCreateView(),ListFargment已經(jīng)重寫過了
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指定了實(shí)例化fragment所用到的類
?
?
b.在程序中添加fragment到ViewGroup
在你的activity運(yùn)行的任何時(shí)候,你都可以添加fragment到你的activity的布局中,你只需指定一個(gè)ViewGroup來放置fragment即可
下面演示fragment的事務(wù)處理
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
? 一旦使用FragmentTransaction改變了fragment,那么必須調(diào)用commit來是它生效
?
每個(gè)fragment都需要一個(gè)唯一標(biāo)識(shí),有三種方法指定唯一標(biāo)識(shí)
1.android:id
2.android:tag
3.如果沒有提供上面兩個(gè)中任何一個(gè),系統(tǒng)則使用他container view的ID作為標(biāo)識(shí)
?
添加一個(gè)沒有UI的fragment
在activity中使用add(Fragment, String)這樣(使用一個(gè)唯一string的tag要比一個(gè)view id好)添加一個(gè)不帶UI的fragment。這樣可以添加fragment,但是因?yàn)樗]有與activity中l(wèi)ayout的View關(guān)聯(lián),所以它不會(huì)收到onCreateView()的調(diào)用,所以也不需要實(shí)現(xiàn)這個(gè)方法。
為fragment提供一個(gè)字符串tag,并不嚴(yán)格局限于沒有UI的fragment,你可以為帶有UI的fragment提供一個(gè)字符串tag,但是如果fragment沒有UI,那么字符串tag是唯一標(biāo)識(shí)它的方式。如果之后你想從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().
?
?
一個(gè)沒有UI的fragment例子(之后的blog中會(huì)有api demos關(guān)于fragment的學(xué)習(xí))
ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
?
管理fragment可以通過FragmentManager
在activity中可以通過getFragmentManager()獲得FragmentManager
執(zhí)行fragment事務(wù)可以通過FragmentTransaction
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
事務(wù)是你提交到activity的一個(gè)改變的集合,可以用FragmentTransaction中的api來執(zhí)行
你也可以save每一個(gè)transaction到一個(gè)由activity管理的back stack中,允許用戶向后導(dǎo)航fragment的改變(類似于向后導(dǎo)航activities)
?
在調(diào)用commit()之前,可是你也許想要調(diào)用addToBackStack(),把transaction添加到fragment的事務(wù)集的一個(gè)的back stack中
這個(gè)back stack是由activity管理的,并且允許用戶按返回鍵返回到上一個(gè)fragment狀態(tài)
?
一個(gè)例子演示了如何用一個(gè)fragment替換另一個(gè)fragment,并且在back stack中保存上一個(gè)狀態(tài)
// 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();
這個(gè)例子中,newFragment替換了當(dāng)前在layout容器中通過ID:R.id.fragment_container標(biāo)識(shí)的fragment
調(diào)用addToBackStack(),這個(gè)“替換”事務(wù)被保存到back stack中,所以用戶可以回退這個(gè)事務(wù)并且通過按back鍵把上一個(gè)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.
如果你添加多項(xiàng)改變到事務(wù)中(例如另一個(gè)add或者remove)并且調(diào)用addToBackStack(),
那么在你調(diào)用commit()之前,所有被實(shí)施的改變作為一個(gè)單一的事務(wù)添加到back stack,Back鍵將會(huì)把他們一起回退
?
這里說一下順序的問題
順序并不在重要, 但是:
必須在最后調(diào)用commit()
如果在同一個(gè)container中添加了多個(gè)fragments,添加的順序決定了他們?cè)趘iew層級(jí)中顯示的順序
?
如果你在執(zhí)行一個(gè)移除fragment操作的事務(wù)時(shí)不調(diào)用addToBackStack()。那么當(dāng)這個(gè)transaction被提交后fragment會(huì)被銷毀,并且用戶不可能回退回去。
相反,如果當(dāng)移除fragment時(shí),你調(diào)用addToBackStack(),那么這個(gè)fragment會(huì)stopped,并且如果用戶導(dǎo)航回去它會(huì)resumed
小提示:對(duì)于每一個(gè)fragment的事務(wù),在commit()之前通過調(diào)用setTransition(),你可以使用一個(gè)過渡動(dòng)畫
?
調(diào)用commit()并不是馬上就執(zhí)行這次事務(wù),恰恰相反,一旦activity的UI線程有能力去完成,F(xiàn)ragmentTransaction就把這次提交列入計(jì)劃到activity的UI線程運(yùn)行
?
如果必要,不管怎樣,你可以從你的UI線程調(diào)用executePendingTransactions()來通過commit()立即執(zhí)行提交了的transaction。通常這樣做并不是必須的,除非transaction是其他線程工作的依賴
警告:只有在activity之前(當(dāng)用戶離開這個(gè)activity時(shí))你可以用commit()提交一個(gè)transaction保存他的狀態(tài)
如果你嘗試在這個(gè)時(shí)間點(diǎn)之后commit,將會(huì)收到一個(gè)異常。這是因?yàn)槿绻鸻ctivity需要恢復(fù),在commit之后的state可能會(huì)丟失。在你覺得可以丟失這次commit的情況下,可以使用commitAllowingStateLoss()
?
?
絕大部分來自對(duì)下面地址的翻譯,英文水平實(shí)在有限,希望拍磚同時(shí)能給予指正。
http://developer.android.com/guide/topics/fundamentals/fragments.html
?
?
轉(zhuǎn)貼請(qǐng)保留以下鏈接
本人blog地址
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

