Android 数据绑定不观察ViewModel中的LiveData
我正在尝试在ViewModel中对LiveData使用数据绑定。但在使用Transformations.map函数时,如果不显式添加观察者,则不会触发该函数。XML中的数据绑定不会为ViewModel中的LiveData生成观察者 LoginFragment.ktAndroid 数据绑定不观察ViewModel中的LiveData,android,mvvm,viewmodel,android-databinding,android-livedata,Android,Mvvm,Viewmodel,Android Databinding,Android Livedata,我正在尝试在ViewModel中对LiveData使用数据绑定。但在使用Transformations.map函数时,如果不显式添加观察者,则不会触发该函数。XML中的数据绑定不会为ViewModel中的LiveData生成观察者 LoginFragment.kt class LoginFragment : Fragment() { var homeViewModel: HomeViewModel? = null companion object { val
class LoginFragment : Fragment() {
var homeViewModel: HomeViewModel? = null
companion object {
val TAG : String = "LoginFragment"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding = DataBindingUtil.inflate<FragmentLoginBinding>(inflater, R.layout.fragment_login, container, false)
.apply {
setLifecycleOwner(this@LoginFragment)
loginButton.setOnClickListener {
signInWithEmail()
}
}
return binding.root
}
/*private fun observeHomeFragmentUIDataLiveData() {
homeViewModel?.homeFragmentUIDataLiveData?.observe(this, Observer {
val email = it.email
Toast.makeText(activity,email, Toast.LENGTH_SHORT).show()
})
}
private fun observeLoginErrorEventLiveData() {
homeViewModel?.loginErrorEventLiveData?.observe(this, Observer {
Toast.makeText(activity,it, Toast.LENGTH_SHORT).show()
})
}*/
/**
* Sign In via Email
*/
fun signInWithEmail(){
val email = email_text_input_layout.editText?.text.toString()
val password = password_text_input_layout.editText?.text.toString()
var cancel : Boolean? = false
var focusView : View? = null
if(password.isEmpty()){
password_text_input_layout.error = getString(R.string.this_field_is_required)
focusView = password_text_input_layout
cancel = true
}
if(email.isEmpty()){
email_text_input_layout.error = getString(R.string.this_field_is_required)
focusView = email_text_input_layout
cancel = true
}
if(cancel!!){
focusView?.requestFocus()
}
else{
homeViewModel?.signInWithEmail(email,password)
/*homeViewModel?.signInWithEmail(email,password)?.observe(this, Observer {
val email = it
Toast.makeText(activity,""+email, Toast.LENGTH_SHORT).show()
})*/
}
}
}
class HomeViewModel(application: Application) : AndroidViewModel(application) {
val homeRepository: HomeRepository?
init {
homeRepository = HomeRepository()
}
// UI Data for HomeFragment
val homeFragmentUIDataLiveData : MutableLiveData<HomeFragmentUIData> = MutableLiveData()
// UI Data for LoginFragment
val loginErrorEventLiveData : MutableLiveData<String> = MutableLiveData()
var isLoginSuccess: LiveData<Boolean>? = null
fun signInWithEmail(email: String, password: String) : LiveData<Boolean>? {
val signInResponseMutableLiveData : MutableLiveData<Any> = homeRepository?.signInWithEmail(email, password)!!
isLoginSuccess = Transformations.map(signInResponseMutableLiveData) { signInResponse ->
when (signInResponse) {
(signInResponse is FirebaseUser) -> {
val firebaseUserEmail = (signInResponse as FirebaseUser).email
homeFragmentUIDataLiveData.value = HomeFragmentUIData(firebaseUserEmail ?: "")
return@map true
}
else -> {
loginErrorEventLiveData.value = signInResponse.toString()
return@map false
}
}
}
return isLoginSuccess
}
}
@BindingAdapter("isGone")
fun bindIsGone(view: View, isGone: Boolean) {
view.visibility = if (isGone) {
View.GONE
} else {
View.VISIBLE
}
}
Android studio版本:
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
build.gradle:
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
您的问题在“解决方案:初始化期间的连线转换”中有详细描述。建议阅读整个博客并进行更改我无法理解解决方案:在初始化过程中为我的案例连接转换。在初始化过程中移动转换,例如视图模型的构造函数。检查示例“Transformations.map函数在未显式添加观察者的情况下不会触发。”-请参见和^F
除非观察者正在查看返回的LiveData对象,否则不会计算转换-我已经告诉过您不需要转换#*map
方法(或MediatorLiveData
)啊。这是有道理的。
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}