[英]In Kotlin Android, viewModel has no observer
我在一個BaseActivity中做了一個工具欄來實現一個通用的,代碼如下。
// BaseActivity
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
lateinit var cartCnt: TextView
private val viewModel by lazy {
ViewModelProvider(this, CartViewModelFactory())[CartViewModel::class.java]
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutId)
mContext = this
viewModel.cartItemList.observe(this){
cartCnt.text = it.size.toString()
}
supportActionBar?.let {
setCustomActionBar()
}
}
open fun setCustomActionBar() {
val defActionBar = supportActionBar!!
defActionBar.elevation = 0F
defActionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
defActionBar.setCustomView(R.layout.custom_action_bar)
val toolbar = defActionBar.customView.parent as Toolbar
toolbar.setContentInsetsAbsolute(0, 0)
cartCnt = defActionBar.customView.findViewById(R.id.cartCnt)
}
}
在 BaseActivity 中,從 CartView Model 中的 MutableLiveData 中觀察到名為 cartCnt(當前購物車中的產品數量)的 TextView 的文本。
如下:cartviewmodel
// CartViewModel
class CartViewModel() : ViewModel() {
private val list = mutableListOf<Cart>()
private val _cartItemList: MutableLiveData<List<Cart>> = MutableLiveData()
val cartItemList: LiveData<List<Cart>> get() = _cartItemList
private val repository by lazy {
CartRepository.getInstance()
}
init {
getAllCartItems()
}
fun getAllCartItems() {
viewModelScope.launch {
repository!!.getRequestMyCartList {
if (it is Result.Success) {
list.addAll(it.data.data!!.carts)
_cartItemList.value = list
}
}
}
}
fun addToCartItem(id: Int) {
viewModelScope.launch {
repository!!.postRequestAddCart(id) {
if (it is Result.Success) {
list.add(it.data.data!!.cart)
_cartItemList.value = list
}
}
}
}
}
View Model 的觀察者只存在於 SplashActivity,它首先繼承了 BaseActivity。 (驗證為 function hasObservers。)。
當我在產品列表頁面點擊購物籃按鈕時,與服務器通信,確認購物籃數據正常放入服務器表中,也確認正常返回200狀態碼。
但是,當有產品列表頁面的 Fragment 聲明 cartViewModel 並調用 addToCartItem function 時,cartViewModel 上沒有附加觀察者。 這是通過hasObservers function確認的部分。
視圖結構大致有MainActivity繼承自BaseActivity,TodayFragment存在於MainActivity中。
而且,TodayFragment 的代碼如下。
// TodayFragment
class TodayFragment : BaseFragment<FragmentTodayBinding>() {
override val layoutId: Int = R.layout.fragment_today
private lateinit var bannerViewPager: BannerRecyclerviewAdapter
private lateinit var productAdapter: ProductHorizonRecyclerviewAdapter
private val cartViewModel by lazy {
ViewModelProvider(this, CartViewModelFactory())[CartViewModel::class.java]
}
override fun init() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initProductRecyclerview()
setValues()
}
override fun setValues() {
HomeViewModel.currentPosition.observe(viewLifecycleOwner) {
binding.bannerViewpager.currentItem = it
}
}
private fun initProductRecyclerview(){
binding.productRecyclerView.apply {
productAdapter = ProductHorizonRecyclerviewAdapter(){
cartViewModel.addToCartItem(it.id)
}
adapter = productAdapter
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
}
}
}
也就是說,當通過TodayFragment中的商品列表頁面調用cartViewModel的addToCartItem function時,cartViewModel的mutableLiveData發生了變化,BaseActivity的cartCnt TextView正在觀察這個變化。
在這種情況下,我想知道為什么第一個SplashActivity,出現在activity棧結構中,有observer,然后在Today Fragment中消失了。
來人幫幫我。
您正在 TodayFragment 中通過向它傳遞一個工廠來重新創建 cartViewModel,這就是它沒有 BaseActivity 觀察器的原因。 在 TodayFragment 中試試這個
private val cartViewModel: CartViewModel by activityViewModels()
或者
private val cartViewModel by lazy {
ViewModelProvider(requireActivity())[CartViewModel::class.java]
}
然后,如果您在 TodayFragment 中調用cartViewModel.addToCartItem()
,它應該在 BaseActivity 中調用觀察者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.