我有这个视图模型:
class MyViewModel : ViewModel() {
var unit = "mi"
}
在我看来,我想选中viewModel.unit == "mi"
复选框。这有效:
<layout>
<data>
<variable name="viewModel" type="com.example.MyViewModel" />
</data>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@{viewModel.unit.equals(`mi`)}" />
</layout>
我想做一些花哨的双向绑定,所以当切换框时,视图模型中的属性也会更改。由于我需要在Boolean和String之间进行转换,因此看来转换器是完成这项工作的正确工具。这是新视图:
<layout>
<data>
<import type="com.example.Converters" />
<variable name="viewModel" type="com.example.MyViewModel" />
</data>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={Converters.convertUnitToChecked(`mi`)}" />
</layout>
以下是转换器:
object Converters {
@InverseMethod("convertCheckedToUnit")
@JvmStatic
fun convertUnitToChecked(unit: String): Boolean {
return unit == "mi"
}
@JvmStatic
fun convertCheckedToUnit(checked: Boolean): String {
return if (checked) "mi" else "km"
}
}
当我尝试构建它时,出现错误:
error: cannot generate view binders java.lang.IllegalStateException: expression does not support two-way binding
at android.databinding.tool.expr.Expr.generateInverse(Expr.java:797)
at android.databinding.tool.expr.MethodCallExpr.generateInverse(MethodCallExpr.java:311)
at android.databinding.tool.InverseBinding.<init>(InverseBinding.java:65)
at android.databinding.tool.BindingTarget.addInverseBinding(BindingTarget.java:70)
at android.databinding.tool.LayoutBinder.<init>(LayoutBinder.java:134)
at android.databinding.tool.DataBinder.<init>(DataBinder.java:60)
at android.databinding.tool.CompilerChef.ensureDataBinder(CompilerChef.java:117)
at android.databinding.tool.CompilerChef.sealModels(CompilerChef.java:369)
at android.databinding.annotationprocessor.ProcessExpressions.writeResourceBundle(ProcessExpressions.java:244)
at android.databinding.annotationprocessor.ProcessExpressions.onHandleStep(ProcessExpressions.java:126)
at android.databinding.annotationprocessor.ProcessDataBinding$ProcessingStep.runStep(ProcessDataBinding.java:247)
at android.databinding.annotationprocessor.ProcessDataBinding$ProcessingStep.access$000(ProcessDataBinding.java:232)
at android.databinding.annotationprocessor.ProcessDataBinding.doProcess(ProcessDataBinding.java:113)
at android.databinding.annotationprocessor.ProcessDataBinding.process(ProcessDataBinding.java:88)
at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)
at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)
at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:79)
at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:35)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:230)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:188)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:99)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:96)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:106)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:81)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:555)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:82)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:546)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:177)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:164)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:54)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1558)
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
(我向转换器添加了@JvmStatic
注释,因为没有这些注释,我会得到另一个错误:cannot find method convertUnitToChecked(java.lang.String)
。)
据我所知,我的构建脚本包含所有必需的位:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
...
dataBinding {
enabled = true
}
}
dependencies {
...
kapt "com.android.databinding:compiler:$androidGradleVersion"
}
我不明白。我跟随these instructions到了那封信。我想念什么?
答案 0 :(得分:0)
您正试图在双向绑定中使用 String 对象。单向绑定也不起作用,这意味着您的 UI 不会对更改做出反应,只会对最初收到的值做出反应。您需要一个用于单向和双向绑定的可观察对象,即 Observable fields、LiveData, StateFlow。