1. 程式人生 > >Android使用newInstance()例項化fragment&setArguments()傳遞引數

Android使用newInstance()例項化fragment&setArguments()傳遞引數

new MyFragment()和MyFragment.newInstance()之間的差別是什麼?應該用哪個呢?

newInstance()方法是一種“靜態工廠方法”,讓我們在初始化和設定一個新的fragment的時候省去呼叫它的建構函式和額外的setter方法。為你的Fragment提供靜態工廠方法是一種好的做法,因為它封裝和抽象了在客戶端構造物件所需的步驟。例如,考慮下面的程式碼:

public class MyFragment extends Fragment {

    /**
     * 靜態工廠方法需要一個int型的值來初始化fragment的引數,
     * 然後返回新的fragment到呼叫者 
     */
public static MyFragment newInstance(int index) { MyFragment f = new MyFragment(); Bundle args = new Bundle(); args.putInt("index", index); f.setArguments(args); return f; } }

不要讓客戶端去呼叫預設的建構函式,然後手動地設定fragment的引數。我們直接為它們提供一個靜態工廠方法。這樣做比呼叫預設構造方法好,有兩個原因:一個是,它方便別人的呼叫。另一個是,保證了fragment的構建過程不會出錯。通過提供一個靜態工廠方法,我們避免了自己犯錯–我們再也不用擔心不小心忘記初始化fragmnet的引數或者沒正確設定引數。

總的來說,雖然兩者的區別只在於設計,但是他們之間的差別非常大。因為提供靜態工廠方法有向上抽象了一個級別,讓程式碼更容易懂。

譯者注:其實提供靜態工廠而不是使用預設建構函式或者自己定義一個有參的建構函式還有至關重要一點。fragmnet經常會被銷燬重新例項化,Android framework只會呼叫fragment無參的建構函式。在系統自動例項化fragment的過程中,你沒有辦法干預。一些需要外部傳入的引數來決定的初始化就沒有辦法完成。使用靜態工廠方法,將外部傳入的引數可以通過Fragment.setArgument儲存在它自己身上,這樣我們可以在Fragment.onCreate(…)呼叫的時候將這些引數取出來。

簡單總結:

使用Fragment.setArguments(Bundle bundle)這種方式來傳遞引數,而不要通過構造方法直接來傳遞引數。

原因:
我們可以知道Activity重新建立時,會重新構建它所管理的Fragment,原先的Fragment的欄位值將會全部丟失,但是通過Fragment.setArguments(Bundle bundle)方法設定的bundle會保留下來。所以儘量使用Fragment.setArguments(Bundle bundle)方式來傳遞引數。