2020年2月16日 星期日

[Android] 移除 DialogFragment 上方空白

markdown 在使用 DialogFragment 的時候會發現上方有一個空白的區域,這是預留給 fragment title 的,若是 DialogFragment 不需要有 title 的話,title 部分空白會讓畫面看起來怪怪的。例如在 [SO](https://stackoverflow.com/questions/28528121/remove-white-background-in-dialogfragment) 上看到的範例圖。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi52qzzySoZL1Wr3dLZw-Os5_0C-m17KJ3PDHN_17yh3l8sehGE_bqZJd4eXMpvw0uaoz3CxI2d4A_0rRlIh0y60cEGkFMrsbwbh2n8NrY8hUeQCLkGWJktlHWJnY_zuqR0gFEfYTM3Omcj/s1600/gfo3j.png) 在網路上有看到兩個方法可以移除 title 留白區域。 1. Window.FEATURE\_NO\_TITLE 2. STYLE\_NO\_TITLE 不知為什麼 Window.FEATURE\_NO\_TITLE 我試過但沒有用,不過用 STYLE\_NO\_TITLE 確實可以消除 title 留白,如下 sample code。
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}

2020年2月10日 星期一

[Android] 螢幕旋轉時 child fragment 和 parent fragment onCreate 執行順序

markdown 最近遇到問題的場景是這樣的,在某個 parent fragment 中用 ViewPager 包含了兩個 child fragment,在 parent fragment 中有儲存了一些變數供給 child fragment 使用,這些變數在 parent fragment 中的 onCreate 初始化,在 child fragment 的 onCreate 中使用。 我預設 parent fragment 的 onCreate 會在 child fragment 的 onCreate 之前執行,這很合理阿,畢竟我們總是先載入 parent fragment 不是嗎? 原本這段程式碼運作的很好,直到有一天測試螢幕轉向,child fragment 的 onCreate 中拋出了 NullPointerException,顯示 parent fragment 中的變數並未初始化,該變數是 null。我發現當螢幕轉向時,child fragment 的 onCreate 會在 parent fragment 的 onCreate 之前執行,導致了這個 exception,這與我先前的認知相反,讓我很驚訝。 查了資料後才發現,原因是當螢幕轉向時,fragment manager 會重新 create 它管理的 fragment,而重新 create 的時間點就是在 [Fragment class](https://developer.android.com/jetpack/androidx/releases/fragment) 的 onCreate 裡面。因此,在我的 parent fragment onCreate 裡面呼叫 super.onCreate 的時候,child fragment 就在這時被 create 出來,並且呼叫了 child fragment 的 onCreate。 仔細想想,這個行為也不是沒有道理,如果 fragment manager 不在 Fragment class 的 onCreate 中去重建 child fragment,它還能在哪個時間點做這件事呢?但是我懷疑有多少人在一開始就查覺到這件事,而不是像我一樣遇到 crash 了才發現。 在查詢 fragment lifecycle 資料時,也看到 [square](https://developer.squareup.com/blog/advocating-against-android-fragments/) 有文章對 fragment 相當感冒,表示應該也有很多人對 fragment lifecycle 的複雜度覺得很難搞吧。 --- Reference: * [After the rotate, onCreate() Fragment is called before onCreate() FragmentActivity](https://stackoverflow.com/questions/14093438/after-the-rotate-oncreate-fragment-is-called-before-oncreate-fragmentactivi) * [Advocating Against Android Fragments](https://developer.squareup.com/blog/advocating-against-android-fragments/) * [Flow和Mortar的调查](https://github.com/hehonghui/android-tech-frontier/tree/master/androidweekly/Square%20%E5%BC%80%E6%BA%90%E5%BA%93Flow%E5%92%8CMortar%E7%9A%84%E4%BB%8B%E7%BB%8D)