3月 25, 2020 Android
### new vs newInstance()

我們有一個 Class 叫 MyFragment.java,內容如下 :

```java
/**
 * my fragment
 */
public class MyFragment extends Fragment {
	
	public static MyFragment newInstance() {
		
		return new MyFragment();
	}
}
```

我們可以通過下面的代碼來生成 MyFragment 的 Object :

```java
// create fragment using new
Fragment f1 = new MyFragment();

// create fragment using static method
Fragment f2 = MyFragment.newInstance();
```

接觸過 Android Programming 的朋友都會見過上面兩種方法,那一種才是正確的方法呢 ?

### Android 的生命週期

上面的答案和 Android 的生命週期有極大的關係,因為 Android 會把不在面前 (顯示中) 的 Fragment Recycle 掉,然後在 Fragment 再出現 (例如使用者按了 Back 制) 時重新建立。這時,Android 是會使用 new Fragment() 的方法建立新的 Fragment 重新顯示。

### 產生問題

如果 Fragment 是沒有參數的話,是沒有任何問題的,像上面的 MyFragment 一樣。我們改寫一下 MyFragment 的內容,讓它可以接收參數 :

```java
/**
 * my fragment
 */
public class MyFragment extends Fragment {

	private int id;
	
	public static MyFragment newInstance() {
		
		return new MyFragment();
	}

	public MyFragment() {
		
		super();
	}

	public MyFragment(int id) {

		super();

		this.id = id;
	}
}
```

有了新的 Constructor 後,我們可以在 `new MyFragment()` 時傳入 id 參數了 !

```java
// create fragment with arguments
Fragment f1 = new MyFragment(1);
```

這樣很完美 ! 但是我們忘記了 Android 可是會因為節省記憶體而把 Fragment 斬掉,然後需要再顯示時以 new Fragment() 重新建立,那我們傳入的 id 不就會一同被斬掉了嗎 ? 

答案是對的,id 會隨著 Fragment 斬掉而一同遠去 ...

### 解決方法

如果有看過另一篇文章講解過 [Android 為 Fragment 傳入參數](https://cdn.19site.net/posts/118)的朋友,會知道我們可以使用 Bundle 來為 Fragment 傳入參數 !

Bundle 不會因為 Fragment 的斬掉而清走,當 Android 重新建立 Fragment 時,先前的 Bundle 會重新連接上,故可以使用 `getArguments()` 取得 Bundle 物件進行設定動作。而 newInstance 的作用就是為了把傳入到 Fragment 的參數規範起來。

我們再把上面的 `MyFragment.java` 改寫一下 :

```java
/**
 * my fragment
 */
public class MyFragment extends Fragment {

	private int id;
	
	public static MyFragment newInstance(int id) {

		Bundle bundle = new Bundle();

		bundle.putInt("id", id);

		MyFragment fragment = new MyFragment()

		fragment.setArguments(bundle);
		
		return fragment ;
	}
}
```

使用這樣的方法來傳入參數,就可以確保 Fragment 重新建立時不會有缺失了 !

```java
// create fragment with arguments
Fragment f1 = MyFragment.newInstance(1);
```

官方說明文件  
https://developer.android.com/reference/android/app/Fragment.html#Fragment()
過去文章
2025 (9)
4 (5)
3 (1)
2 (3)
2024 (25)
11 (3)
10 (3)
9 (1)
3 (18)
2022 (6)
10 (1)
6 (2)
5 (1)
3 (1)
1 (1)
2021 (21)
11 (7)
7 (1)
6 (2)
5 (2)
4 (6)
3 (2)
2 (1)
2020 (92)
12 (1)
11 (2)
10 (4)
9 (10)
8 (5)
7 (1)
6 (3)
5 (1)
4 (4)
3 (25)
2 (7)
1 (29)
2019 (57)
12 (25)
11 (7)
9 (25)