碎片Fragment
https://developer.android.google.cn/guide/components/fragments.html
一、什么是Fragment
Fragment(碎片)就是小型的Activity,它是在Android3.0時(shí)出現(xiàn)的。Fragment是表現(xiàn)Activity中UI的一個(gè)行為或者一部分。
可以把fragment想象成activity的一個(gè)模塊化區(qū)域,有它自己的生命周期,接收屬于它自己的輸入事件,并且可以在activity運(yùn)行期間添加和刪除(有點(diǎn)像一個(gè)可以在不同的activity中重用的“子Activity”)。
Fragment必須被嵌入到一個(gè)activity中。它們的生命周期直接受其宿主activity的生命周期影響。當(dāng)一個(gè)activity正在運(yùn)行時(shí),就可以獨(dú)立地操作每一個(gè)Fragment,比如添加或刪除它們。
Fragment可以定義自己的布局、生命周期回調(diào)方法,因此可以將fragment重用到多個(gè)activity中,因此可以根據(jù)不同的屏幕尺寸或者使用場(chǎng)合改變fragment組合。
二、如何創(chuàng)建一個(gè)Fragment
1、為Fragment定義一個(gè)布局
2、定義類繼承Fragment
3、重寫類中的onCreateView()方法,返回一個(gè)View對(duì)象作為當(dāng)前Fragm
ent的布局。
fragment第一次繪制它的用戶界面的時(shí)候,系統(tǒng)會(huì)調(diào)用onCreateView()方法。為了繪制fragment的UI,此方法必須返回一個(gè)作為fragment布局的根的view。如果fragment不提供UI,可以返回null。
/*** 定義類繼承Fragment*/public class TitleFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {//使用打氣筒填充生成一個(gè)View對(duì)象,fragment_title是一個(gè)布局的根節(jié)點(diǎn)View view = inflater.inflate(R.layout.fragment_title, null);return view;}}三、如何將Fragment添加到Activity
Activity必須在清單文件中進(jìn)行聲明,但是Fragment不需要,Fragment只需要在Activity的布局文件中聲明就可以了。
<fragment android:id="@+id/fmt_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:name="com.itheima.fragment.TitleFragment" />注意:代碼中的四個(gè)屬性是必須的要給的,“android:name”屬性:指定了在layout中實(shí)例化的Fragment類是哪個(gè)。當(dāng)系統(tǒng)創(chuàng)建這個(gè)activity
layout時(shí),它實(shí)例化每一個(gè)在layout中指定的Fragment,并調(diào)用它們的onCreateView()方法,來(lái)獲取每一個(gè)Fragment的layout,系統(tǒng)將從Fragment返回的View直接插入到<fragment>元素所在的地方每一個(gè)fragment都需要一個(gè)唯一的標(biāo)識(shí),如果activity重啟,系統(tǒng)可以用來(lái)恢
復(fù)Fragment,并且可以用id來(lái)捕獲Fragment來(lái)處理事務(wù),例如移除它。
有3種方法來(lái)為一個(gè)fragment提供一個(gè)ID,具體如下所示:
- 為android:id屬性提供一個(gè)唯一ID;
- 為android:tag屬性提供一個(gè)唯一字符串;
- 如果以上2個(gè)你都沒(méi)有提供,系統(tǒng)將使用容器view的ID;
四、如何切換Fragment
要在activity中管理Fragment,需要使用FragmentManager可以通過(guò)調(diào)用activity的getFragmentManager()取得它的實(shí)例。
案例:點(diǎn)擊不同的按鈕切換到不同的Fragment進(jìn)行顯示。具體實(shí)現(xiàn)步驟:
1、設(shè)置布局文件:添加三個(gè)按鈕用于切換Fragment,并在按鈕下方
添加一個(gè)FrameLayout用來(lái)替換成響應(yīng)的Fragment。
2、創(chuàng)建三個(gè)Fragment,SportsFragment、NewsFragment、GameFragment。
其余兩個(gè)Fragment跟SportsFragment代碼一致,只是布局文件不同。
3、添加切換Fragment的邏輯,這個(gè)是新聞?lì)l道按鈕的點(diǎn)擊事件
sports()方法、games()方法同上,因此不再給出代碼清單。
4、運(yùn)行程序,效果如下
Fragment的生命周期
Fragment的生命周期和activity生命周期很像,其生命周期方法如下所示。
- onAttach:綁定到activity
- onCreate:創(chuàng)建fragment
- onCreateView: 創(chuàng)建fragment的布局
- onActivityCreated: activity創(chuàng)建完成后
- onStart: 可見(jiàn), 不可交互
- onResume: 可見(jiàn), 可交互
- onPause: 部分可見(jiàn), 不可交互
- onStop:不可見(jiàn)
- onDestroyView: 銷毀fragment的view對(duì)象
- onDestroy: fragment銷毀了
- onDetach: 從activity解綁了
五、Fragment的向下兼容
Fragment是在Android3.0才推出的,若想在3.0的低版本下使用Fragment,則需要執(zhí)行下面2步:
1、把所有Fragment和FragmentManager改成support-v4包下的類
2、把Activity的繼承改為FragmentActivity(support-v4包下的)
六、Fragment之間的通信案例
案例:創(chuàng)建一個(gè)用于顯示選項(xiàng)卡的Fragment和一個(gè)用于顯示內(nèi)容的Fragment,當(dāng)選項(xiàng)卡切換時(shí),使內(nèi)容的Fragment信息跟著一起切換。具體實(shí)現(xiàn)步驟如下所示:
1、先創(chuàng)建選項(xiàng)卡Fragment和內(nèi)容Fragment,并在activity_main.xml布
局文件中進(jìn)行設(shè)置,其布局效果如下:
2、為選項(xiàng)卡Fragment創(chuàng)建布局文件,其布局效果如下:
3、添加內(nèi)容區(qū)域Fragment的代碼邏輯
4、添加選項(xiàng)卡區(qū)域Fragment的代碼邏輯
public class TabFragment extends Fragment implements OnItemClickListener {private String[] datas;private int[] picIds;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroupcontainer, Bundle savedInstanceState) {//直接使用ListView作為布局,因此不需要布局文件ListView listView = new ListView(getActivity());//定義一些常量數(shù)據(jù)作為冊(cè)數(shù)數(shù)據(jù)datas = new String[]{"新聞", "體育", "財(cái)經(jīng)", "社會(huì)", "娛樂(lè)", "國(guó)際"};picIds = new int[]{R.drawable.a0, R.drawable.a1, R.drawable.a2, R.drawable.a3, R.d rawable.a4, R.drawable.a5};//設(shè)置點(diǎn)擊事件listView.setOnItemClickListener(this);//聲明一個(gè)ArrayAdapter對(duì)象ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_expandable_list_item_1, datas);//給ListView設(shè)置AdapterlistView.setAdapter(adapter);//返回視圖return listView;}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//獲取當(dāng)前的title和圖片idString title = datas[position];int picId = picIds[position];//獲取Fragment管理器FragmentManager manager = getFragmentManager();//通過(guò)ID選擇出ContentFragment對(duì)象ContentFragment fragment = (ContentFragment) manager.findFragmentById(R.id.fragment_content);//調(diào)用ContentFragment的方法,給ContentFragment傳遞參數(shù),實(shí)現(xiàn)不同F(xiàn)ragment直接的通信fragment.setTitleAndImage(title, picId);}}Fragment與Activity如何交互?
這里我不再詳細(xì)介紹那寫比較常規(guī)的方式,例如靜態(tài)變量,靜態(tài)方法,持
久化,application全局變量,收發(fā)廣播等等。
首先我們來(lái)介紹使用Handler來(lái)實(shí)現(xiàn)Fragment與Activity
的交互。第一步,我們需要在Activity中定義一個(gè)方法用來(lái)設(shè)置Handler對(duì)象。
public void setHandler(Handler handler) {
mHandler = handler;
}
第二步,在Fragment中的回調(diào)函數(shù)onAttach()中得到Fragment所在Activity,并調(diào)用setHandler方法,設(shè)置Handler。該Handler在Fragment中定義,用來(lái)接收消息與Fragment進(jìn)行交互。
然后我們可以在Activity中發(fā)送消息給Fragment中的Hanlder進(jìn)行交互。
public void inter(View view) { Message msg = new Message(); msg.obj = edit.getText().toString(); msg.what = 1; mHandler.sendMessage(msg); }Fragment回退棧實(shí)現(xiàn)
public class MainActivity extends FragmentActivity implements OnClickListener {private FragmentA fragmentA;private FragmentB fragmentB;private FragmentC fragmentC;private List<Fragment> fragmentsList = new ArrayList<Fragment>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.btnA).setOnClickListener(this);findViewById(R.id.btnB).setOnClickListener(this);findViewById(R.id.btnC).setOnClickListener(this);fragmentA = new FragmentA();fragmentB = new FragmentB();fragmentC = new FragmentC();//將三個(gè)Fragment添加到幀布局中/** 1. 獲取FragmentManger*/FragmentManager fragmentManager = getSupportFragmentManager();/** 2. 通過(guò)FragmentManager獲取到事務(wù)管理器*/FragmentTransaction transaction = fragmentManager.beginTransaction();/** 3. 將Fragment添加到幀布局中*/transaction.add(R.id.fl, fragmentA, "FragmentA").add(R.id.fl, fragmentB,"FragmentB").add(R.id.fl, fragmentC,"FragmentC").hide(fragmentB).hide(fragmentC).commit();addToBackStack(fragmentA);}private void addToBackStack(Fragment fragment) {if (fragmentsList.contains(fragment)) {//先將老的對(duì)象移除fragmentsList.remove(fragment);//將Fragment添加到集合的最后fragmentsList.add(fragment);}else {fragmentsList.add(fragment);}}@Overridepublic void onBackPressed() { // super.onBackPressed();if (fragmentsList.size()>1) {//移除最頂端的FragmentfragmentsList.remove(fragmentsList.size()-1);//將下一個(gè)Fragment給顯示出來(lái)showFragment(fragmentsList.get(fragmentsList.size()-1));}else {//如果當(dāng)前棧中沒(méi)有Fragment或者只有一個(gè)Fragment,直接退出Activityfinish();}}private void showFragment(Fragment fragment) {FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();transaction.hide(fragmentA).hide(fragmentB).hide(fragmentC).show(fragment).commit();}@Overridepublic void onClick(View v) {FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();transaction.hide(fragmentA).hide(fragmentB).hide(fragmentC);switch (v.getId()) {case R.id.btnA:transaction.show(fragmentA);addToBackStack(fragmentA);break;case R.id.btnB:transaction.show(fragmentB);addToBackStack(fragmentB);break;case R.id.btnC:transaction.show(fragmentC);addToBackStack(fragmentC);break;default:break;}//把當(dāng)前事務(wù)添加到會(huì)退棧中 // transaction.addToBackStack(null);transaction.commit();}}總結(jié)
以上是生活随笔為你收集整理的碎片Fragment的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: View类的xml属性和相关方法说明
- 下一篇: Layout动画:在android布局发