Android Studio 3.6
这是我的viewModel:
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProviders
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
class BluetoothPageViewModel(application: Application) : AndroidViewModel(application) {
private val isSearchingTableModeLiveData = MutableLiveData<Boolean>()
private val isInitModeLiveData = MutableLiveData<Boolean>()
private val errorMessageLiveData = MutableLiveData<String>()
private val toastMessageLiveData = MutableLiveData<String>()
fun isInitModeLiveData(): LiveData<Boolean> {
return isInitModeLiveData
}
fun isSearchingTableModeLiveData(): LiveData<Boolean> {
return isSearchingTableModeLiveData
}
fun getErrorMessageLiveData(): LiveData<String> {
return errorMessageLiveData
}
fun getToastMessageLiveData(): LiveData<String> {
return toastMessageLiveData
}
在这里分割了对此 viewmodel 的订阅以及成功调用Observer.onChanged()
class BluetoothPageFragment : Fragment() {
private lateinit var bluetoothPageViewModel: BluetoothPageViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dataBinding =
DataBindingUtil.inflate(inflater, R.layout.bluetooth_page_fragment, container, false)
val view = dataBinding.getRoot()
dataBinding.setHandler(this)
init()
return view
}
private fun init() {
val context = this.context
val viewViewModelProvider = ViewModelProviders.of(this)
bluetoothPageViewModel = viewViewModelProvider.get(BluetoothPageViewModel::class.java)
bluetoothPageViewModel.isInitModeLiveData().observe(this, // SUCCESS CALL
Observer<Boolean> { isInitMode ->
})
}
在我的活动中,订阅此 viewmodel 和不打 Observer.onChanged()
import androidx.lifecycle.ViewModelProviders
class QRBluetoothSwipeActivity : AppCompatActivity() {
private lateinit var bluetoothPageViewModel: BluetoothPageViewModel
private fun init() {
val viewViewModelProvider = ViewModelProviders.of(this)
bluetoothPageViewModel = viewViewModelProvider.get(BluetoothPageViewModel::class.java)
val customFragmentStateAdapter = CustomFragmentStateAdapter(this)
customFragmentStateAdapter.addFragment(QrPageFragment())
bluetoothPageFragment = BluetoothPageFragment()
customFragmentStateAdapter.addFragment(bluetoothPageFragment)
dataBinding.viewPager2.adapter = customFragmentStateAdapter
initLogic()
}
private fun initLogic() {
dataBinding.viewPager2.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
positionObservable.set(position)
}
})
bluetoothPageViewModel.getToastMessageLiveData() // this not call
.observe(this,
Observer<String> { message ->
Toast.makeText(this, message, Toast.LENGTH_LONG).show()
})
}
为什么不打getToastMessageLiveData()
?
答案 0 :(得分:1)
您在活动和片段中都呼叫ViewModelProviders.of(this)
,但这是不同的上下文。因此,在您的情况下,您将实例化两个不同的BluetoothPageViewModel实例,因此不会调用onChanged
回调。
为了在活动和Fragment之间共享一个实例,您应该从同一上下文中获取viewModelProvider。
在您的活动中:
ViewModelProviders.of(this)
在您的片段中:
ViewModelProviders.of(activity)
或
activity?.let {
val bluetoothPageViewModel = ViewModelProviders.of(it).get(BluetoothPageViewModel::class.java)
bluetoothPageViewModel.isInitModeLiveData().observe(this, // SUCCESS CALL
Observer<Boolean> { isInitMode ->
})
}
答案 1 :(得分:1)
在两种情况下都使用
ViewModelProviders.of(this)
它表示您希望此视图模型具有不同的作用域。一种来自活动范围,另一种来自片段范围。如果您要分享。 如果要共享视图模型,则必须使用单个作用域。我建议使用较大元素的范围,在这种情况下为活动。 在片段中,您应该致电
ViewModelProviders.of(activity)
这应该可以解决您的问题。