傳入 ViewModel
1. 建立 ViewModel、在 Fragment 中使用
import androidx.lifecycle.ViewModel
class PViewModel: ViewModel() {
}
2. 在Fragment 中,將 ViewModel 傳入 composable function
注意:在正式版應用程式中,只能由畫面層級可組合項參照
ViewModel
。如果子項可組合項需要來自ViewModel
的資料,最佳做法是只傳遞子項可組合項需要的資料,不要傳遞整個 ViewModel 的資料。詳情請參閱「螢幕 UI 狀態」。可組合項沒有自己的 ViewModel 例項,相同的例項會在可組合項以及代管該 Compose 程式碼的生命週期擁有者 (Activity 或 Fragment) 之間共用。
class BlankFragment2 : Fragment() {
private var _binding: FragmentBlank2Binding? = null
private val viewModel: PViewModel by viewModels()
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentBlank2Binding.inflate(inflater, container, false)
val view = binding.root
binding.apply {
composeView.setContent {
// You're in Compose world!
MaterialTheme {
PlantDetailDescription(viewModel)
}
}
}
return view
}
}
@Composable
fun PlantDetailDescription(pViewModel : PViewModel) {
Surface {
Text("Hello Compose")
}
}
從可組合項觀察 LiveData
1. 在 ViewModel 中建立 LiveData 的變數
class PViewModel: ViewModel() {
private val _score = MutableLiveData(0)
val score: LiveData<Int>
get() = _score
}
2. 在可組合項觀察 LiveData
注意:LiveData.observeAsState()
會開始觀察 LiveData,並以State
物件表示其值。每當有新的值發布至 LiveData 時,傳回的State
都會更新,造成所有State.value
的用法重新組合。
要使用 observeAsState() 需要加上 :
implementation ("androidx.compose.runtime:runtime-livedata:1.5.4")
@Composable
fun PlantDetailDescription(pViewModel : PViewModel) {
val pScore by pViewModel.score.observeAsState()
pScore?.let {
PlantScore(pScore!!)
}
}
/*由於 LiveData 發出的值可能是 null,因此您必須將其用法納入 null 檢查中。
因此,也為了方便重複使用,建議您將 LiveData 的消費與監聽分割至不同的可組合項。
讓我們新建一個名為 PlantScore 的可組合項,用來顯示 Score 資訊。*/
@Composable
fun PlantScore(score: Int){
Text("分數是$score")
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentBlank2Binding.inflate(inflater, container, false)
val view = binding.root
binding.apply {
composeView.setContent {
// You're in Compose world!
MaterialTheme {
PlantDetailDescription(viewModel)
}
}
}
return view
}
使用屬性委託 (by) 可以不用 .value
- 下列三種方式皆在可組合項中宣告 MutableState 物件( 這三種宣告作用相等,僅做為語法糖,運用在不同狀態用途中。) :
- val mutableState = remember { mutableStateOf(default) }
- var value by remember { mutableStateOf(default) }
- 使用這種方式,因為是使用屬性委託而非=,所以不用每次都輸入 .value
- val (value, setValue) = remember { mutableStateOf(default) }
0 comments:
張貼留言