2020年2月16日 星期日

[Android] 移除 DialogFragment 上方空白

在使用 DialogFragment 的時候會發現上方有一個空白的區域,這是預留給 fragment title 的,若是 DialogFragment 不需要有 title 的話,title 部分空白會讓畫面看起來怪怪的。例如在 SO 上看到的範例圖。

在網路上有看到兩個方法可以移除 title 留白區域。

  1. Window.FEATURE_NO_TITLE
  2. STYLE_NO_TITLE

不知為什麼 Window.FEATURE_NO_TITLE 我試過但沒有用,不過用 STYLE_NO_TITLE 確實可以消除 title 留白,如下 sample code。

  1. @Override
  2. public void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setStyle(DialogFragment.STYLE_NO_TITLE, 0);
  5. }

2020年2月10日 星期一

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

最近遇到問題的場景是這樣的,在某個 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 的 onCreate 裡面。因此,在我的 parent fragment onCreate 裡面呼叫 super.onCreate 的時候,child fragment 就在這時被 create 出來,並且呼叫了 child fragment 的 onCreate。

仔細想想,這個行為也不是沒有道理,如果 fragment manager 不在 Fragment class 的 onCreate 中去重建 child fragment,它還能在哪個時間點做這件事呢?但是我懷疑有多少人在一開始就查覺到這件事,而不是像我一樣遇到 crash 了才發現。

在查詢 fragment lifecycle 資料時,也看到 square 有文章對 fragment 相當感冒,表示應該也有很多人對 fragment lifecycle 的複雜度覺得很難搞吧。


Reference: