fragment與activity。什么時(shí)候使用?

Fragment與Activity。什么時(shí)候用什么時(shí)候不用?

回答: 看需求!

個(gè)人覺(jué)得推薦場(chǎng)景

(使用Fragment完全替換Activity,而Activity用來(lái)管理Fragment或者把fragment當(dāng)作一個(gè)輕量級(jí)activity使用)

  • 當(dāng)你一個(gè)Activity需要模塊化的時(shí)候,你可以單獨(dú)寫(xiě)一個(gè)Fragment并且嵌套在任何一個(gè)界面,不用擔(dān)心重復(fù)代碼。

  • 一般主頁(yè)的每個(gè)tab都是用Fragment,類(lèi)似的一個(gè)頁(yè)面下有多個(gè)布局需要切換的時(shí)候感覺(jué)用Fragment很方便

  • 布局在不同的設(shè)備上比如手機(jī)和平板上的適配

  • 比如 App 中有一個(gè)新用戶(hù)注冊(cè)功能,包括設(shè)置用戶(hù)名、密碼、手機(jī)號(hào)等等流程,設(shè)計(jì)師在 UI 設(shè)計(jì)上將每個(gè)流程單獨(dú)設(shè)計(jì)成一個(gè)界面,引導(dǎo)用戶(hù)一步步操作。作為開(kāi)發(fā)人員,如果將每一個(gè)完善信息的流程單獨(dú)設(shè)置成一個(gè) Activity 的話(huà)操作起來(lái)就比較繁瑣,并且也不易于應(yīng)用里的邏輯處理,而如果使用 Fragment 并結(jié)合回退棧的話(huà),就非常合適了


    FragmentManager fm = getSupportFragmentManager();

    FragmentTransaction ft = fm.beginTransaction();

    ft.hide(firstStepFragment);

    if (secondStepFragment==null){

        ft.add(R.id.fl_content, secondStepFragment);

    }else {

        ft.show(secondStepFragment);

    }

    ft.addToBackStack(null);

    ft.commit();


注意:這里使用了 hide() 方法,而不是 replace() 方法,因?yàn)槲覀儺?dāng)然希望用戶(hù)返回上一步操作時(shí),之前設(shè)置的內(nèi)容不會(huì)消失。

Activity管理Fragment的思路:(曾經(jīng)用過(guò))
  • 當(dāng)然別忘了FragmentManager。管理著 正在activity里顯示的fragment們(用list)以及detach之后跟view hiearchy斷開(kāi)聯(lián)系的被放進(jìn)backstack的fragment:

  • 建一個(gè)hashmap,用于存放已實(shí)例過(guò)的fragment,要復(fù)用的時(shí)候直接拿出來(lái),而且還可以解決Fragment 重疊問(wèn)題;

  • 寫(xiě)一個(gè)Basefragment,子Fragment繼承與它,自定義接口,在activity里實(shí)現(xiàn)接口方法,因此activity可以根據(jù)待實(shí)例化fragment的屬性進(jìn)行管理控制。(這也是觀(guān)察著模式)

    具體實(shí)現(xiàn)方式如下:

   public class BaseFragment extends Fragment implements View.OnClickListener{

       public interface IOneFragmentClickListener{

           void onOneFragmentClick();

       }

       @Nullable

       @Override

       public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

           View contentView = inflater.inflate(R.layout.fragment_one, null);

           contentView.findViewById(R.id.edt_one).setOnClickListener(this);

           return contentView;

       }

       @Override

       public void onClick(View v) {

           if (getActivity() instanceof IOneFragmentClickListener){

                ((IOneFragmentClickListener) getActivity()).onOneFragmentClick();

           }

       }

   }

只要在宿主 Activity 實(shí)現(xiàn) Fragment 定義的對(duì)外接口 IOneFragmentClickListener,便可以實(shí)現(xiàn) Fragment 調(diào)用 Activity 的功能。

fragment的使用

作為 Activity 界面的一部分,F(xiàn)ragment 的存在必須依附于 Activity,并且與 Activity 一樣,擁有自己的生命周期,同時(shí)處理用戶(hù)的交互動(dòng)作。同一個(gè) Activity 可以有一個(gè)或多個(gè) Fragment 作為界面內(nèi)容,并且可以動(dòng)態(tài)添加、刪除 Fragment,靈活控制 UI 內(nèi)容,也可以用來(lái)解決部分屏幕適配問(wèn)題。
另外,support v4 包中也提供了 Fragment,兼容 Android 3.0 之前的系統(tǒng)(當(dāng)然,現(xiàn)在 3.0 之前的系統(tǒng)在市場(chǎng)上已經(jīng)很少見(jiàn)了,可以不予考慮),使用兼容包需要注意兩點(diǎn):

  • Activity 必須繼承自 FragmentActivity;

  • 使用 getSupportFragmentManager() 方法獲取 FragmentManager 對(duì)象;

fragment 生命周期:

一邊看一邊提出一些問(wèn)題:

  • attach跟add怎么理解?inflate呢?
  • attach有什么作用?有什么好處,因此適合什么場(chǎng)景?
image

個(gè)人對(duì)提出問(wèn)題的回復(fù):

Applications should generally not implement a constructor. Prefer
{@link #onAttach(Context)} instead. It is the first place application code can run where
the fragment is ready to be used - the point where the fragment is actually associated with its context. Some applications may also want to implement {@link #onInflate} to retrieve
attributes from a layout resource, although note this happens when the fragment is attached.</pre>

  • attach:將fragment與Activirty聯(lián)系起來(lái),通過(guò)context。所以通過(guò)fragment startActiviotyForResult 其實(shí)也是Activity start的,回調(diào)onActivityResult() 也是應(yīng)該由activity處理。 </pre>
  • add:將fragment加到ViewHiearchy中,通過(guò)把fragment加到manager管理的active的fragment的List里。
  • onInflate():保存布局里的屬性

Called when a fragment is being created as part of a view layout
inflation, typically from setting the content view of an activity. This may be called immediately after the fragment is created from a <fragment>
tag in a layout file. Note this is <em>before</em> the fragment's
{@link
#onAttach(Activity)} has been called; all you should do here is
parse the attributes and save them away. <p>This is called every time the fragment is inflated, even if it is
being inflated into a new instance with saved state. It typically makes sense to re-parse the parameters each time, to allow them to change with different configurations.</p> </pre>

attach與detach及回退棧的配合,如果當(dāng)你detach fragment時(shí),那么被移除的fragment就被停止了(沒(méi)有消亡,但視圖已經(jīng)銷(xiāo)毀了),如果用戶(hù)導(dǎo)航回來(lái)重新加載這個(gè)fragment,它將會(huì)重新啟動(dòng),視圖也會(huì)重新創(chuàng)建,如果你沒(méi)有把事務(wù)加入到堆棧中,當(dāng)fragment被remove時(shí),這個(gè)fragment也就消亡了。

通信方式


通常,F(xiàn)ragment 與 Activity 通信存在三種情形:

  • Activity 操作內(nèi)嵌的 Fragment

    由于 Activity 持有所有內(nèi)嵌的 Fragment 對(duì)象實(shí)例(創(chuàng)建實(shí)例時(shí)保存的 Fragment 對(duì)象,或者通過(guò) FragmentManager 類(lèi)提 供的 findFragmentById() 和 findFragmentByTag() 方法也能獲取到 Fragment 對(duì)象),所以可以直接操作 Fragment;

  • Fragment 操作宿主 Activity;
    Fragment 通過(guò) getActivity() 方法可以獲取到宿主 Activity 對(duì)象(強(qiáng)制轉(zhuǎn)換類(lèi)型即可),進(jìn)而可以操作宿主 Activity;那么很自然的,獲取到宿主 Activity 對(duì)象的 Fragment 便可以操作其他 Fragment 對(duì)象。

  • Fragment 操作同屬 Activity中的其他 Fragment。
    高內(nèi)聚,低耦合。Fragment 做好自己的事情即可,所有涉及到 Fragment 之間的控制顯示等操作,都應(yīng)交由宿主 Activity來(lái)統(tǒng)一管理。

流行的tab欄結(jié)構(gòu)可以為:
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,872評(píng)論 0 10
  • 早起,下樓到小區(qū)看書(shū)45分鐘,可以聽(tīng)到鳥(niǎo)兒渣渣叫,雨后空氣很好 今天晚上的月亮特別圓,很美,準(zhǔn)備回家上單反,然后給...
    Jane小白917閱讀 344評(píng)論 4 1
  • 這幾天手機(jī)很奇怪,頻頻出問(wèn)題,動(dòng)不動(dòng)就死機(jī),喜馬拉雅聽(tīng)一半兒就卡,下不了東西,微信聯(lián)系人全部消失..... 首...
    貓公主喵閱讀 162評(píng)論 0 0
  • “不要??!”秦子路大喊著從床上掙扎著坐起來(lái)。月光從床前半開(kāi)的窗戶(hù)闖入這個(gè)小房間,停在了被褥上。他右手正摸著心口,剛...
    不知道怎么取名字耶閱讀 252評(píng)論 1 0
  • 相思如雨 我在小城牽馬留下了細(xì)細(xì)的馬蹄 相思如雨 我在閣樓挑燈輕舞了我的瘦筆 相思如雨 我在城墻吹響了我那朱紅長(zhǎng)笛...
    詩(shī)的故事閱讀 434評(píng)論 1 2

友情鏈接更多精彩內(nèi)容