无法使用数据绑定Android与ViewModel中的XML通信

知识养成了思想,思想同时又在融化知识。这篇文章主要讲述无法使用数据绑定Android与ViewModel中的XML通信相关的知识,希望能为你提供帮助。
我正在尝试使用MVVM模式从xml与viewmodel进行通信,反之亦然。我之前曾在数据绑定方面工作并成功使用Live Data-Dagger-MVVM。最近,我尝试创建一个新项目,从那时起我无法使用XML和viewmodel跟踪响应。无论是来自XML的onClick- > ViewModel,还是来自View- > XML的textview的赋值都是有效的。但没有崩溃或任何事情,只是它不起作用。我添加了所有相关文件[MainActivity,activity_main,viewModel,Dagger Module,build.gradle]
如果有人能告诉我这里出了什么问题,我将非常感激。
activity_main.xml中

< ?xml version="1.0" encoding="utf-8"?> < layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> < data> < variable name="viewmodel" type="aveek.com.vm.ui.home.MainActivityViewModel"/> < /data> < android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> < TextViewandroid:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{viewmodel.balanceText}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:clickable="true" android:onClick="@{() -> viewmodel.clickData()}" app:layout_constraintTop_toTopOf="parent" /> ... < /layout>

我激活了。
class MainActivity : AppCompatActivity(),LifecycleOwner {@Inject lateinit var binding : ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) binding.setLifecycleOwner(this) with(binding){ this.viewmodel?.let { it.balanceText.set( "Aveek testing") it.data.observe(this@MainActivity, Observer { Toast.makeText(this@MainActivity, "Data is now : $it", Toast.LENGTH_SHORT).show() }) } } }

我ACTIVITYVOD.COM
class MainActivityViewModel : ViewModel() { val data = https://www.songbingjia.com/android/MutableLiveData< Boolean> () val balanceText = ObservableField< String> () fun clickData(){ data.value = false } }

我激活了模型.Cut
@Module classMainActivityModule{/** * provides binding toMain Activity from respective XML * @property viewModel * @property context * @return binding of the view */ @Provides fun binding(context: MainActivity, viewModel : MainActivityViewModel) : ActivityMainBinding { val binding = DataBindingUtil.setContentView< ActivityMainBinding> (context, R.layout.activity_main) binding.viewmodel = viewModel return binding } }

的build.gradle
apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply plugin: 'kotlin-android-extensions'apply plugin: 'kotlin-kapt'android { compileSdkVersion 27 defaultConfig { applicationId "aveek.test" minSdkVersion 15 targetSdkVersion 27 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } dataBinding { enabled = true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility javaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }kapt { generateStubs = true }dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:multidex:1.0.2' implementation 'com.android.support:design:27.1.1' implementation "android.arch.lifecycle:extensions:1.1.0" //annotationProcessor "android.arch.lifecycle:compiler:1.1.0"kapt "com.android.databinding:compiler:$androidPluginVersion"annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVersion" kapt "com.google.dagger:dagger-compiler:$daggerVersion" kapt "com.google.dagger:dagger-android-processor:$daggerVersion"implementation "com.google.dagger:dagger:$daggerVersion" implementation "com.google.dagger:dagger-android:$daggerVersion" implementation "com.google.dagger:dagger-android-support:$daggerVersion" kapt "com.google.dagger:dagger-compiler:$daggerVersion"testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso- core:3.0.2'}ext{ kotlin_version = '1.2.31' androidPluginVersion = '3.1.0' daggerVersion = '2.13' }

答案
您将无法使用任何生成的方法将变量设置为绑定,因为除了ViewDataBinding之外没有常见的超类,因此您将被迫使用反射,或者您可以使用方便方法setVariable():
binding.setVariable(BR.viewModel, viewModel);

另一答案我怀疑,问题在于Dagger注射。也许我已经用错误的方法实现了但是如果在没有DI的情况下运行,则viewmodel非常好。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java) binding = DataBindingUtil.setContentView(this, R.layout.activity_main) binding.viewmodel = viewModelbinding.setLifecycleOwner(this) mLifecycleRegistry = LifecycleRegistry(this).apply { markState(Lifecycle.State.CREATED) } with(binding){ this.viewmodel?.let { it.balanceText.set( "Aveek testing") it.data.observe(this@MainActivity, Observer { Toast.makeText(this@MainActivity, "Data is now : $it", Toast.LENGTH_SHORT).show() }) } } }

【无法使用数据绑定Android与ViewModel中的XML通信】所以,我已经浏览了DI代码并发现在MainActivity.onCreate()中我正在这样做
AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)

这基本上覆盖了数据绑定行为。所以我更新了这样的代码
AndroidInjection.inject(this) super.onCreate(savedInstanceState) //setContentView(R.layout.activity_main) // and initiated binding here as injecting binding from module before setting content won't be effective val binding = DataBindingUtil.setContentView< ActivityMainBinding> (this, R.layout.activity_main)

并删除
//@Inject //lateinit var binding : ActivityMainBinding

现在它完美无缺..

    推荐阅读