關於 Android,用多個 activity,還是單 activity 配合 fragment?

發現目前還是挺多 app 是單activity多 fragment 實現的,比如 Gmail, Google Play, 知乎,等等。我想請教下這樣有些什麼坑嗎?額,已知的坑有 activity 重建時,可能會導致多重 fragment 出現,生命周期複雜等,但是還是有解決辦法,不知道是否還有其他坑。相比純 activity 做有哪些優勢和劣勢?我覺得用 fragment 打開的新頁面給我最直覺的感受是打開速度更開了,打開新的 activity 老是有一個慢慢的感覺。

謝謝各位。

================================================================================================================================================

我發現我提問描述得不太清除,然後描述被修改過,導致更不清楚了,我不是想問fragment好不好,而是問單activity配合多fragment的方式好不好,單個activity配合多fragment,所有頁面都用fragment實現,用這個主activity來控制。

========================================================================

我是這樣判斷知乎新版和 Google Play 是單 activity 配合多 fragment 的, 在 device monitor 中可以看到,新版知乎的每個頁面都可以看到 drawerLayout (搖一搖反饋里沒有), 並且在這下面都有一個 id 為 content_layer_primary 的 FrameLayout,幾乎每個頁面都能打開 drawer ,實現這種功能的最簡單辦法就是打開新頁面都是在這個 FrameLayout 上面添加 fragment 就行了。

然後 Google Play 的分析是這樣的:大多數頁面(設置等除外),在這裡面都能看到 drawerLayout,下面有個 id 為 outer_content_frame 的 FrameLayout,也是每個頁面都能打開 drawer ,同上,雖然也有其他做法能實現這樣的,但是最簡單的還是單 activity 多 fragment 的方法。

以上。

所有的都是我的猜測。如有不對的地方請解惑下,謝謝。


------------------------------

2016-08-23 15:40

Fragment,Activity狀態保存最佳實現,請參見我專欄的一篇譯文,這篇文章採用GIF動圖配合代碼講解的方式,十分淺顯易懂,由於之前我看過了,這裡把它翻譯了過來,希望更多的人能夠受益。由於知乎不能顯示GIF動圖,請至原文查看(原文鏈接在專欄譯文中),最後感謝原作者nuuneoi的精彩文章。

保存/恢復Activity和Fragment狀態的最佳實踐(譯) - Code雜貨鋪 - 知乎專欄

----------------------

目錄

  • 封裝BaseFragment基類
  • 使用靜態工廠方法newInstance(...)來獲取Fragment實例
  • Fragment狀態保存/現場恢復
  • 避免錯誤操作導致Fragment的視圖重疊
  • 避免非同步操作導致Fragment崩潰(待補充)
  • Fragment里監聽虛擬按鍵和實體按鍵的返回事件

  • 使用最大化的DialogFragment來實現浮動層級視圖(待補充
  • 判斷一個頁面該使用Fragment還是Activity

------------------------------

2015-01-22 21:40

更新了一個如何在Fragment中監聽返回鍵事件的小技巧,是我目前認為最好的方式。

我回答的都是一些比較基礎的,常用的,所以沒有涉及到一些深層次的問題。可以看看其他的回答,有些寫的很不錯。

在業務場景下到底是使用Fragment還是Activity我在答案最後也有提及到,我所參與的項目的三個子項目(包括我沒參與過的N多項目,之前做code review有看過源碼的那部分),基本上都是大量使用Fragment來做視圖部分,組裝更加靈活。

我們的視頻文檔組件開發也是以Fragment為基礎來做的,我們接入項目的時候只需要預留Layout,之後組件會用Fragment的形式來填充Layout。

Fragment+Activity並不意味著一定只有一個Activity,我們項目就分LoginActivity,SplashActivity,HomeActivity,參見我最後的回答。

所以我覺得到底用不用是肯定毋庸置疑的,我們不能因為一個東西學習成本高,需要注意的點多,就否認它來帶的便利。

Fragment還存在一些坑,是我在項目中遇到過的,明天會補充一下。

感謝 @碗盆 補充

補充一下 @麵條的回答

  • 避免錯誤操作導致Fragment的視圖重疊

視圖重疊是因為fragment已經發生了內存泄漏。

activity的創建、銷毀完全託管到systemserver(ams),而fragment一般是手動new一個對象再add到systemserver,所以這裡就有問題了。

fragment生命周期開始於add,結束於remove。不管app中間怎麼變化,崩潰、進程被回收,只要沒有remove,android框架都會自動創建、恢復fragment的狀態。

---------------------------------------------------

2015-01-22 15:20

正準備出門去接女友回她家,發現居然破200個贊了。

評論里問打包好沒有的,我人都在重慶了,順豐小哥很快的好嗎?!ヽ(?ω??)? ,今天正在家裡做了一天清潔,拖地,擦地,擦桌子,收拾我從福州帶回來的一推破爛,去樓下收了一個快遞,又下樓去物業拿了一桶送的油,然後各種洗衣服,下周開始每天要給女友做晚飯了(要是一個人我可以叫外賣)。

所以各位有女友還沒結婚的想裸辭朋友可要考慮清楚了,我女友給我岳父說我裸辭了,岳父當時就不說話了(。?`ω′?)。

晚上估計會補一點Fragment的其他使用小技巧,都是我工作中遇到過的,有用的東西,比較適合新手。

爭取把這個回答寫好,不辜負這200個贊。

------------------------------------------------------

謝邀,我正在打包行李中,看到這個問題來答一答。

首先Fragment帶來的便利以及足以讓我們無視它可能會導致的麻煩了,而且很多麻煩都是自己使用方法不正確導致的。

畢竟相比於Activity來說,創建一個Fragment所需系統資源相比Activity來說更少,然而控制卻更為靈活。

我所參與的項目基本上不用Activity來做UI展示,這部分職責都移交給fragment來實現。

Fragment一般分為兩類,一類是有UI的Fragment,可以作為頁面,作為View來展示,另一類是用沒有UI的Fragment,一般用作保存數據。

至於題主所說的重疊,以及創建多個的問題,都是自己使用不當導致的,你需要get正確的fragment使用方法。

好了,不說了,我要打包顯示器了,晚了快遞就要下班了。

有時間在補充。

------------------分割線-----------------------

打包完了,快遞小哥還沒來,又開始下雨了。。。我先寫著。

  • 封裝BaseFragment基類

例如為了實例化View,抽象一個getLayoutId方法,子類無需關心具體的創建操作,父類來做View的創建處理。同時可以提供一個afterCreate抽象函數,在初始化完成之後調用,子類可以做一些初始化的操作,你也可以添加一些常用的方法在基類,例如ShowToast().

public abstract class BaseFragment extends Fragment {
protected View mRootView;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(null == mRootView){
mRootView = inflater.inflate(getLayoutId(), container, false);
}
return mRootView;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
afterCreate(savedInstanceState);
}

protected abstract int getLayoutId();

protected abstract void afterCreate(Bundle savedInstanceState);
}

感謝 @xiaoxiao Mi 補充,已修改

不過有一點,public View onCreateView 這個方法中返回之前判斷一下你的mRootView是null再inflate,這樣會比較好,在ViewPager中隨著頁面滑動這個方法會調用多次,inflate過了之後就直接用就好了。

  • 使用靜態工廠方法newInstance(...)來獲取Fragment實例

可以在Google的代碼中發現這種寫法,好處是接收確切的參數,返回一個Fragment實例,避免了在創建Fragment的時候無法在類外部知道所需參數的問題,在合作開發的時候特別有用。

還有就是Fragment推薦使用setArguments來傳遞參數,避免在橫豎屏切換的時候Fragment自動調用自己的無參構造函數,導致數據丟失。

public static WeatherFragment newInstance(String cityName) {
Bundle args = new Bundle();
args.putString(cityName,"cityName");
WeatherFragment fragment = new WeatherFragment();
fragment.setArguments(args);
return fragment;
}

  • Fragment狀態保存/現場恢復

不要在Fragment裡面保存ViewState!

不要在Fragment裡面保存ViewState!

不要在Fragment裡面保存ViewState!

為了讓你的代碼更加清晰和穩定,最好區分清楚fragment狀態保存和view狀態保存,

如果某個屬性屬於View,則不要在Fragment中做它的狀態保存,除非屬性屬於Fragment。

每一個自定義View都有義務實現狀態的保存,可以像EditText一樣,設置一個開關來選擇是否保存

比如說:android:freezeText="true/false"。

public class CustomView extends View {

...

@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
// 在這裡保存當前狀態
return bundle;
}

@Override
public void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
// 恢復保存的狀態
}

...

}

處理fragment狀態保存,例如保存從伺服器獲取的數據。

private String serverData;

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("data", serverData);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
serverData = savedInstanceState.getString("data");
}

  • 避免錯誤操作導致Fragment的視圖重疊

這個問題很簡單,在add或者replace的時候,調用含有TAG參數的那個方法,之後再add相同TAG的Fragment的話,之前的會被替換掉,也就不會同時出現多個相同的Fragment了。

public class WeatherFragment extends Fragment {
//TAG
public static final String TAG = WeatherFragment.class.getSimpleName();

不過為了最大限度的重用,可以在Activity的onCreate(Bundle savedInstanceState)中判斷savedInstanceState是否不為空;

不為空的話,先用getSupportFragmentManager(). findFragmentByTag()找一下,找到實例就不用再次創建。

WeatherFragment fragment = null;

if(savedInstanceState!=null){
fragment = getSupportFragmentManager().findFragmentByTag(WeatherFragment.TAG);
}

if(fragment == null){
fragment = WeatherFragment.newInstance(...);
}

  • Fragment里監聽虛擬按鍵和實體按鍵的返回事件

我見過很多方法,這個方法是最好的,給rootView設置一個OnKeyListener來監聽key事件

mRootView.setFocusable(true);
mRootView.setFocusableInTouchMode(true);
mRootView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//不一定是要觸發返回棧,可以做一些其他的事情,我只是舉個栗子。
getActivity().onBackPressed();
return true;
}
return false;
}
});

  • 使用最大化的DialogFragment來實現浮動層級視圖

如果你有一個列表頁面,例如知乎,點擊Item打開詳情頁,你可以使用最大化的DialogFragment來顯示詳情頁,此時並不需要提供一個具體的ContainerId即可顯示,因為詳情頁一般情況下在Phone上都是佔據滿屏幕的,用DialogFragment即可。

不過這並不是最好的做法,在要考慮到Tablet適配的情況下,如下圖

Tablet上是嵌入的,而手機上是佔據全部空間。

此時可以把詳情頁單純用Fragment實現,滿足Tablet設備嵌入的需要,在手機上可以使用全屏的DialogFragment來包裹Fragment,之後只需要DialogFragment.show(...)即可。

從這裡就可以看出,Fragment的使用其實是非常靈活的。

  • 判斷一個頁面該使用Fragment還是Activity

如果後一個頁面不需要用到前一個頁面的太多數據,推薦用Activity展示,否則最好用Fragment( 當然這也不是絕對的)。

例如SplashActivity和MainActivity沒有太多的耦合度,此時可以分成兩個Activity。

  • 後記

上面所說的也只是Fragment的一部分使用方法,不過已經可以滿足常用的開發需求了。

這些坑其實我在項目裡面呆的時候都沒遇到,自然而然的就照著同事的方式處理了,GET到很多之前不知道的東西,不過你要是遇到了,用百度一搜,一大堆出來,真正有用的沒幾個,而且都是你copy我,我copy你的。

還有一個原因是國內大部分人都沒精力和時間或者心思來做原創分享,也沒這個風氣。

Fragment應該算是很基礎的東西了,而且3.0以後就有了,你說這個東西難嗎?也不難,就是要注意的點很多,用多了自然也就知道了。


補充一下 @麵條的回答

  • 避免錯誤操作導致Fragment的視圖重疊

視圖重疊是因為fragment已經發生了內存泄漏,這是一個很嚴重的問題。

activity的創建、銷毀完全託管到systemserver(ams),而fragment一般是手動new一個對象再add到systemserver,所以這裡就有問題了。

fragment生命周期開始於add,結束於remove。不管app中間怎麼變化,崩潰、進程被回收,只要沒有remove,android框架都會自動創建、恢復fragment的狀態。

再說兩點需要注意的地方:

  • FragmentTransaction非同步執行相關問題。FragmentTransaction#commit函數是非同步執行的(其把本次transaction的所有操作添加到消息隊列里),不注意這一點可能會出現一些奇怪的問題。比如閃屏問題:view的顯示隱藏是同步執行的,而fragment的hide、show是非同步執行的,所以可能會碰到view隱藏了,而fragment的界面還沒顯示,導致閃屏。不過android也提供了FragmentManager#executePendingTransactions方法,強制同步執行。
  • 調用Fragment#startActivityForResult方法時,只有直接添加到activity里的fragment能收到onActivityResult回調,child fragment是收不到onActivityResult的。具體原因可以查看相應的實現代碼,這裡就不多說了。


如果是界面之間關聯比較大,傳遞數據量太多,用fragment,要是兩個界面之間互相沒有關聯,我是不願意用fragment的。

哪怕我對它源碼再熟,其他同事也不一定能避開我遇到過的坑,咱們寫代碼,可維護,易維護是必須的,用fragment各種饒,和activity交互還只能用介面(憋跟我說用廣播,用什麼eventbus!!)


看了一下上面的答案,只有 @潘飛答到了點子上。

如果真如多數人所說的,Fragment各個方面完爆Activity,那Google團隊為什麼不直接淘汰掉Activity,或者封裝一個App總Activity,剩下的都用Fragment不就行了嗎?

Fragment性能的確比Activity好,但是從性能方面比較Fragment和Activity無意義,因為它們的應用場景不同。

Activity更傾向於一個整體模塊容器,而Fragment是其中的子模塊。可以理解成一個工廠(App)有N個生產不同產品的產房(Activity),每個廠房(Activity)裡面有生產N類子產品的機器(Fragment)。

所以,Activity的存在可以對應用更好的結構化和模塊化的劃分,讓應用有更健壯和清晰的層次,而Fragment可以讓將應用的功能細化和具象化。兩者沒有好壞之分,根據功能劃分粒度來選取合適的載體才是正確的架構方式。

--------------

用我之前做的一個App簡單舉個例子,並不全面,拋磚引玉。

App提供課表、新聞、成績、電費、地圖、圖書館等功能模塊,首先根據產品策略,主頁提供是三個大入口,分別為課表、學校、我。然後,在各入口中,提供其餘功能模塊入口,如學校中提供新聞、地圖,「我」中提供成績單、圖書館等功能嗎。

那我的設計思路是這樣的,提供入口的主頁可以設計成一個Activity和三個Fragment,主頁的規劃如圖。

(隨手畫的,見諒)

接著,在學校頁面,提供幾個功能模塊的入口,拿其中新聞舉例。點開後,新聞頁面是一個Activity,新聞公告列表、新聞詳情分別是這個Activity附屬的Fragment。同理,成績單功能模塊是一個Activtity,學期成績單、總成績單分別是兩個附屬的Fragment。

----------------------------update 補充「學校」界面---------------------------------


先說說fragment的優點,放到實際開發中來說

1.使用fragment來顯示頁面,系統資源消耗更小,直觀的表現就是切換view時的速度變快,對用戶更加友好。而且切換動畫的配置非常簡單,同時又強大,能夠適應更多需求

2.fragmentmanager能夠方便的管理fragment棧,對於切換操作時自由度更高。而activity是依賴系統自己的任務棧來處理,當然你也可以自己寫一個管理器來保持每個activity的引用達到這樣的效果,但是你必須對每個activity的啟動模式有相當的了解,即使這樣,因為當你調用finish的時候並不會同步的結束當前activity,可能會導致一些依賴於activity的資源釋放問題,實際上要達到更高自由度效果的切換效果,activity開銷要大不少

3.fragment界面耦合度低,可以作為ui組件開放給其他開發人員使用,要想把一個可復用的頁面給別人用,fragment顯然最符合我們的需求,只需要一個fragment標籤就可以輕鬆解決問題。如果只是單單用一個viewgroup來達到這樣的效果,關於生命周期的部分都要全部自己再寫一遍

當然,所有的這些都是視你的業務需求來決定的,對於頻繁被其他activity調用的單頁顯然是單獨做成activity比較好,而如果只是單任務棧的模型下,fragment完全可以勝任任何場景


以前我覺著用很多 Activity 很 low ,現在發現是自己太 navie 。我的建議是不能顯著提升開發者效率的情況下,還是盡量用 Activity 。另外問題評論里說的很對。新版知乎是一個 Activity ,其他的都是 Fragment ,開發過程我也略有了解。所以更加建議不要迷信 Fragment 。


這個問題提的不好。

絕大部分這類問題的答案都是按照具體需求和實現成本來決定用什麼(技術方案)

參見設計規範對於標準安卓樣式的設計,可以參考Googlde的這一節《Navigation》,對於標準化的Activity/Fragment使用場景進行了描述。同類型的頁面使用Fragment完成跳轉,通過使用返回鍵進行pop,Up鍵進行整個Activity的退出。從設計角度請儘可能遵從這一節。

其次是業務(實現)上,這個的情況就比較多,首先,通過ActivityGroup+單個Activity,或者在Acitvity內通過各種自定義View(自己維護生命周期、隱藏顯示之類的,support.v4的包出來之前大家都是這麼乾的),都能實現Fragment的效果,無非就是健壯性、可擴展性比官方出的差很多罷了。所以,並不一定要拘泥於「我一定要用什麼,什麼一定就比什麼好」對程序進行使用。

在使用場景上,官方的app就不多說了,以知乎舉例(新版本沒用,不在範圍內):

· 最外層不用講了,標準的主Activity中套入Navigation-drawer+Fragment,控制內部的幾個頁面,首頁、發現、關注、收藏等;在業務層級上,都屬於內容列表展示區域,在第一層級;

· 搜索Activity中包含內容Fragment和人Fragment

· 消息Activity中包含三個Fragment:動態、贊和私信,私信點擊又可以跳到對話列表Activity

· 提問Activity中包含三個Fragment

· 設置Activity中包含若干個Fragment,從列表到詳細內容

· 問題頁面Activity、問題詳情Activity、話題Activity、人物詳情Activity等等,其中都嵌套了詳情、多個內容的Fragment

以及其他,就不一一列舉了。

在對於自己程序設計的坑裡面,Activity對比Fragment的優劣是毫無意義的,我再強調一下,代碼都是人寫出來的,從純UI的問題上講,Fragment和Activity並沒用到什麼私有API,完全可以用不同的內容實現相同的效果。Fragment最初產生是為了跨解析度的問題,詞如其名,即通過管理分塊(碎片)Fragment,更靈活地布局,能在手機、TV、平板上實現一套代碼,多種樣式的需求。

多數情況下,有些人會建議在多個界面上有數據交互/保存的時候,使用Fragment作為頁面,我對此持不支持也不反對的態度,這是解決辦法之一,但是如果你的應用出現類似的問題,仔細考慮一下你的數據模型、存儲模型是否設計的不夠好?

其次是性能問題,Activity在生命周期上來看,是少於Fragment的,Fragment還多了一些跟宿主Activity的交互;而Activity又有ActivityManager這種跟FragmentManager差不多的管理東西,其實性能上沒什麼可比較性,基本都差不多;如果你的Activity啟動速度過慢,應該先考慮是否是代碼的問題,耗時操作?UI組件、嵌套過於複雜?或者多考慮使用ViewStub這種東西。

純Activity的話,也有壞處。最淺顯的問題,類似ios裡面的uinavigation,fragment已經提供了一套成型的基於某個Activity的管理方式,一個最大的好處就是可以提供生命周期的數據共享。其次就是我上面說的問題了,可以實現一套代碼,多種樣式。

我贊同其他答案的說法,你說的問題可能是你沒完全理解fragment的順序導致的。畢竟Fragment其實就是個硬套出來的自定義View(誤)。

說了這麼多,我還是希望你看一下我下面的話:

Fragment只是一種官方提供的靈活組件,請優先遵從你的項目設計!

Fragment只是一種官方提供的靈活組件,請優先遵從你的項目設計!

Fragment只是一種官方提供的靈活組件,請優先遵從你的項目設計!


一個Activity實例配合多個Fragment入棧, 最大的弊病會導致入棧越深, 布局層次越深, 界面越卡.

推薦的做法是同一個Activity多個實例, 中間抽離出中間層, 自己將Activity的事件分發給中間層.

通過Intent將要實例的中間層類名傳過去, 在Activity中實例化該中間層, 然後Activity將所有事件分發給中間層.

如果不想自己處理事件路由, 可以直接用Fragment做中間層, 缺點是頂層會多嵌套一層FrameLayout, 和過多的事件, 一般也用不上, 不如自己實現可控.

比如閃屏就是VirtualActivity + SplashFragment

主界面就是VirtualActivity + MainFragment + {AFragment + BFragment + CFragment}


哪個我都不用

我個人傾向在DecorView上add window,把每一個頁面抽象成一個window。

好處是不需要處理fragment那一堆曖昧的生命周期和非同步回調導致的崩潰,也不會有多個activity跳轉的那麼差的性能。而且debug會更簡單。因為是window,也都是獨立繪製的沒那麼多重繪。封裝好之後的後續開發很簡單,我記得工作一年左右的新人倆小時就教懂了,之後也沒有過bug。

壞處就是封裝起來複雜度有點高,要控制window的棧和自己控制生命周期,自己添加回調。不過都自己搞也不需要依賴那麼多系統api,靈活性高控制力強,代價是框架寫起來很需要理解Android源碼才行。


最近引入kotlin,開始整理一些類。

看到BaseFragment中的東西,一陣詫異。我為何要寫這些又繞又麻煩的東西?

後來才想起,這都是為了處理「少量Activity+多數Fragment」引入的一些小坑。

忽然就覺得挺有趣。

當初我也是「少量Activity+多數Fragment」的擁護者。理由千千萬萬。

如今又回到Activity的世界,有明確需要才會使用Fragment。

「少量Activity+多數Fragment」留下了各種小坑,雖然都可以避免,但現在想想這種坑的原因,本質就是Android並沒有設計讓大家這樣使用Fragment吧。或者說,這不是Android的初衷。


14年夏初開始,間隔做過幾個安卓應用, 都是以單Activity多Fragment的形式在做。而Activity,只用在必須要用的地方,比如應用入口,這裡說的入口不只是啟動入口(手動喚起),還包括和第三方應用交互時,接受回調的入口(自動喚起);比如宿主FragmentTabHost,因為setRetainInstance方法不能用在嵌套的Fragment內。

做這些項目期間,遇到了不少問題。不得不承認,佔用了個人相當多的項目時間。而且基本上每個項目里,都會有一些新問題冒出來。

在我看來,使用這種方式要面對大量問題的背後,是SDK的設計者,並沒有給Fragment一個足夠清晰的定位;而Activity又很重(上帝視角、性能、Activity之間的通信),欠缺靈活性(切換、導航控制),一些人不願忍受Activity的霸道專橫萎靡拖沓,又沒找到別的路可循,於是權衡利弊,走到了以Fragment為主來組織UI邏輯的羊腸小路。

這條小路是如此的崎嶇,很多人都在各自的項目里分頭跋涉,而至今為止,似乎也並沒有一個流行起來的框架/庫,幫助大家走得從容一些,甚至沒有一份來自來官方的行走指南。

我一直在懷疑,這條路是否走錯了。

然而自己缺少足夠的才智和積累,並不足以悟道真相。

直到前不久同事給我推薦了一篇文章,

[Square:從今天開始拋棄Fragment吧!](Square:從今天開始拋棄Fragment吧!)

引用文章結尾處的一段話

我們曾為 Fragment 的誕生滿心歡喜,幻想著 Fragment 能為我們帶來種種便利,然而這一切不過是場虛空大夢,我們最後發現騎著白馬的 Fragment 既不是王子也不是唐僧,只不過是人品爆發撿了只白馬的乞丐罷了

故事到這裡,還遠沒有結束。

有人在旁路辟開一道荊棘,而我們依然需要摩西,

依然需要成熟的、被優良設計的框架/庫和指南,來幫助我們繼續攀行。


目前activity加fragment比較流行,其主要原因是因為橫屏和豎屏的適配,以及平板和手機的適配。還有一個原因是大量的開源庫也是使用fragment的,用到這些庫就必須使用fragment了。


凡是可能移動並嵌入到多個地方的功能模塊都用fragment實現。


我們內部是使用多Acitvity開發的。一般情況下推薦使用多個Activity,或者混合使用。

單Activity類似於單頁應用,不過因為Fragment本身存在很多坑,且單Activity會造成生命周期混亂。

當然這些都是可以通過一定的手段解決,不過這也加大了新人的學習成本,認真想想不太值得。


我比較傾向於用fragment,因為fragment單純看就是一個view,能實現很多炫酷的跳轉動畫,而且還可以復用,假如你應用有好幾個地方有相同或類似的展示和實現邏輯,當然,有時候還是要用activity的,看情況選擇,你比如啟動頁


vp+fragment,fragment用hide和show方法....


一般來說,這個更多的取決於產品設計,而不是程序員。

比如新版知乎的幾個選項卡,顯然用fragment更合適。

但你說你做一個電商購物,業務邏輯都是後繼和返回的關係,弄成fragment就沒必要了,反而是activity更好些。

總體來說,fragment適合平行頁面較多的應用,使用fragment可以增強使用者的流暢體驗;而頁面之間是先後業務關係的應用,用fragment不是最好。


activity配合fragment,這個可以從頁面效果來看,activity之間的切換有很明顯的切換過程,整個界面切換。fragment之間的切換,明顯比activity好


最近看著一塊,看了Fragment生命周期源碼,基本會用,其實我是一個比較糾結的人,就是一直想知道google為什麼這麼設計fragment,google的工程師怎麼想到的,想不通的時候特別糾結,不過看了各位的回答受益匪淺。向你們學習。


這個我覺得要看具體的業務需求吧


推薦閱讀:

有哪些開源的採用 Material Design 的 Android 程序呢?
移動APP切圖標準?
學習android架構的步驟?
有人知道uber登錄界面那個視頻是怎麼實現的嗎?

TAG:Android開發 | Java | Android |