賞金將在 6 天后到期。此問題的答案有資格獲得 50聲望賞金。 hushed_voice想引起更多關注這個問題:
需要知道如何在啟影片面被禁用之前停止 Fragment 被初始化
我的 MainActivity 中有一個 FragmentContainerView,它使用導航圖。
<androidx.fragment.app.FragmentContainerView
android:id="@ id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav" />
我希望我的片段等到我從 API 獲得一些資料后再隱藏我的啟影片面。我正在使用 android 12啟影片面。這就是我試圖完成它的方式(來自檔案):
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
setContentView(R.layout.activity_main)
//Set up an OnPreDrawListener to the root view.
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
// Check if the initial data is ready.
return if (mainActivityViewModel.isDataReady()) {
// The content is ready; start drawing.
Timber.tag("Splash").d("data ready")
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
Timber.tag("Splash").d("data not ready")
// The content is not ready; suspend.
false
}
}
}
)
只有在我獲得資料后,啟影片面才會消失。但問題是我的 Fragments 回呼就像onViewCreated在我的資料準備好之前就被呼叫了。這會導致問題,因為我依賴在初始螢屏期間獲取的資料來執行某些任務。
我如何確保在我的啟影片面消失之前我的片段不會被初始化?
uj5u.com熱心網友回復:
只有在我獲得資料后,啟影片面才會消失。但問題是我的片段回呼(如 onViewCreated)甚至在我的資料準備好之前就被呼叫了。
活動和片段生命周期回呼僅由系統在適當的時間觸發。它們不能由開發人員觸發;對此無法控制。所以,你不能阻止onCreateView, onViewCreated,.. 的發生。即你不能從初始化中停止活動/片段;否則你可能會有 ANR。
更詳細
在某些后臺任務完成之前,不應抓住活動/片段的初始化;這實際上會導致 ANR。
當您使用addOnPreDrawListener;抓住活動的根布局的繪圖時 這并不意味著活動的初始化(即onCreate())被占用,因為兩者都是異步作業的,并且onCreate(), onStart(), & onResume()將正常回傳。
片段的回呼也是如此,片段的初始化(即onCreateView()... onViewCreated)與活動的onCreate().
現在,由于起始目的地片段的初始化依賴于 API 資料;那么這個特定的片段不應該是開始目的地。
因此,要解決此問題,您需要創建一些初始螢屏片段作為不依賴 API 資料的起始目的地。
根據 API 傳入資料,您可以決定通過以下方式導航到原始片段navController:
return if (mainActivityViewModel.isDataReady()) {
// Do the transaction to the original fragment through the navController
// The content is ready; start drawing.
Timber.tag("Splash").d("data ready")
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
// Not transaction is needed, keep the splash screen fragment
Timber.tag("Splash").d("data not ready")
// The content is not ready; suspend.
false
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/490325.html
上一篇:如何將片段背景關系傳遞給配接器?
