知识养成了思想,思想同时又在融化知识。这篇文章主要讲述无法使用数据绑定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
现在它完美无缺..
推荐阅读
- Android Studio中单选按钮的onClick()的替代选项
- Android - MVVM中ViewModel状态的最佳实践()
- 通过mvvm android进行异常处理
- 在MVVM架构Android中启动服务的正确位置是什么
- Android中的MVVMCross绑定不起作用
- 使用Android MVP Clean Architecture实现交互者
- Android登录屏幕(双向绑定EditText和TextView)
- 没有Dagger2的Android Kotlin MVVM结构
- android viewmodels之间的inter通信