西安電子科技大學(xué)機(jī)電工程學(xué)院 郭雨佳 韓雨辰 趙明英 朱俊杰
在現(xiàn)有智能手機(jī)操作系統(tǒng)中,Android占絕對(duì)主導(dǎo)地位。Activity是Android四大組件之一,F(xiàn)ragment是一種嵌套在Activity中的UI組件。由于多個(gè)Activity的進(jìn)棧出棧會(huì)造成程序卡頓,所以實(shí)際開發(fā)的時(shí)候,為了達(dá)到更好的用戶體驗(yàn)大多會(huì)使用Fragment來設(shè)計(jì)用戶交互界面。正因如此,Activity和Fragment之間的通信便顯得尤為重要。本文分析了兩者間的多種通信方式,提出接口回調(diào)方式是進(jìn)行通信的最佳方式。
在Android程序設(shè)計(jì)中,Activity是重要的控件之一。一個(gè)Activity就代表了應(yīng)用程序中的一個(gè)頁面。每次點(diǎn)擊頁面進(jìn)行跳轉(zhuǎn)的時(shí)候,需要將當(dāng)前的Activity的狀態(tài)保存至堆棧,下次使用的時(shí)候再?gòu)亩褩V腥〕鰜碚故窘o用戶。這樣不斷的進(jìn)出堆棧,將會(huì)導(dǎo)致應(yīng)用程序運(yùn)行過程中出現(xiàn)卡頓,嚴(yán)重影響用戶體驗(yàn)。為了解決這一問題,Android系統(tǒng)引入了Fragment。Fragment并不是一個(gè)獨(dú)立的部分,是一種可以嵌入到Activity中的UI控件。Fragment的出現(xiàn)使在同一個(gè)Activity上進(jìn)行界面的切換成為現(xiàn)實(shí)。
創(chuàng)建Fragment的方法有動(dòng)態(tài)和靜態(tài)兩種。前者就是通過Java代碼來創(chuàng)建Fragment的實(shí)例,后者則是在編寫Activity的xml布局文件時(shí)通過<fragment>標(biāo)簽實(shí)現(xiàn)控件的創(chuàng)建。
動(dòng)態(tài)創(chuàng)建的具體步驟:
第一步:在當(dāng)前Activity的布局文件中創(chuàng)建FrameLayout并為其設(shè)置id;
第二步:鼠標(biāo)移動(dòng)到當(dāng)前包名處并單擊右鍵,選擇new->Fragment->Blank Fragment,創(chuàng)建新的Fragment;
第三步:在Activity的onCreat()方法中使用代碼將fragment添加到FrameLayout。
靜態(tài)創(chuàng)建的具體步驟:
第一步:鼠標(biāo)移動(dòng)到當(dāng)前包名并單擊右鍵,選擇new->Fragment->Blank Fragment,創(chuàng)建新的Fragment;
第二步:在在xml文件中創(chuàng)建fragment控件,并通過name屬性引入fragment文件,同時(shí)可以為fragment創(chuàng)建一個(gè)id,以便后續(xù)的使用。
由于Fragment是嵌入到Activity中的一種控件,所以它不會(huì)單獨(dú)存在,它必須附著到Activity中。基于此,F(xiàn)ragment的生命周期會(huì)受到Activity生命周期的影響。Fragment和Activity有著相似的生命周期,它會(huì)隨著Activity的暫停而暫停,隨著Activity的銷毀而銷毀。我們就可以對(duì)附著在Activity上面的Fragment進(jìn)行操作的前提是這個(gè)Activity是處于正常運(yùn)行中的。常見的操作有添加、替換和刪除等。Fragment的生命周期如圖1所示。
圖1 Fragment的生命周期示意圖
通過調(diào)用getSupportFragmentManager()函數(shù)可以拿到用來操作Fragment的Manager,然后通過它的findFragmentByTag()或者findFragmentById()拿到我們需要通信的Fragment實(shí)例(如果Fragment是直接在XML中定義的,那么就使用findFragmentById()拿到Fragment),然后就可以對(duì)拿到的Fragment進(jìn)行各種操作了。
我們可以通過getActivity().findViewById()的方法獲取Fragment附著的Activity中的控件,但是這種方式代碼耦合性太強(qiáng),不利于代碼的移植和優(yōu)化,所以更多情況下采用回調(diào)方法來進(jìn)行二者的通信。在Fragment中聲明一個(gè)接口并提供一個(gè)接口的引用變量,接口中定義所需的方法,然后讓Activity實(shí)現(xiàn)此接口并按照需要重寫接口中的方法。當(dāng)Fragment需要訪問Activity中數(shù)據(jù)時(shí),只需要通過接口實(shí)例調(diào)用接口方法并將參數(shù)傳遞,具體的操作代碼則在Activity中的接口方法中完成。
由于Fragment是依附于Activity的,所以Fragment之間通信不能直接通信,必須依靠所依附的Activity。為了降低代碼之間的耦合,可以通過回調(diào)實(shí)現(xiàn)Fragment之間通信。
任意Fragment之間要想通信必須通過他們所屬的Activity來完成,不能是多個(gè)Fragment之間的直接通信、調(diào)用。同理,F(xiàn)ragment要訪問它所附著的Activity中的信息也得在Activity中進(jìn)行。Fragment與其所附著的Activtiy之間通信的最佳方式應(yīng)該是:
在發(fā)起事件的Fragment中定義一個(gè)接口,接口中聲明你的方法;
在onAttach()方法中要求Activity實(shí)現(xiàn)接口;
在Activity中實(shí)現(xiàn)該接口并重寫該方法。