使用 Kotlin Multiplatform Mobile (KMM) 的多平台应用程序中的 DataBinding 错误
Posted
技术标签:
【中文标题】使用 Kotlin Multiplatform Mobile (KMM) 的多平台应用程序中的 DataBinding 错误【英文标题】:DataBinding error in multiplatform app using Kotlin Multiplatform Mobile (KMM) 【发布时间】:2021-03-29 05:29:32 【问题描述】:我是 Kotlin 的新手,我遇到了 DataBinding 的问题 - C不能访问类 ViewModel。检查您的模块类路径是否存在缺失或冲突的依赖项。 但 DataBinding 在块 buildFeatures
中连接我的 build.gradle.kts(androidApp):
plugins
id("com.android.application")
kotlin("android")
id("kotlin-android")
id("com.squareup.sqldelight")
id("kotlinx-serialization")
id("kotlin-kapt")
android
compileSdkVersion(30)
defaultConfig
applicationId = "com.rompos.activator.kmm.androidApp"
minSdkVersion(26)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
buildTypes
getByName("release")
isMinifyEnabled = false
buildFeatures
viewBinding = true
dataBinding = true
kotlinOptions
jvmTarget = JavaVersion.VERSION_1_8.toString()
packagingOptions
pickFirst("META-INF/*.kotlin_module")
kapt
generateStubs = true
correctErrorTypes = true
dependencies
implementation(project(":shared"))
implementation("com.google.android.material:material:1.2.1")
implementation("androidx.core:core-ktx:1.3.2")
implementation("androidx.appcompat:appcompat:1.2.0")
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.recyclerview:recyclerview:1.1.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("androidx.activity:activity-ktx:1.1.0")
implementation("androidx.fragment:fragment-ktx:1.2.5")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.2.0")
implementation("androidx.lifecycle:lifecycle-common-java8:2.2.0")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.2.0")
implementation("com.squareup.sqldelight:android-driver:1.4.4")
implementation("org.kodein.di:kodein-di:7.1.0")
出现错误的片段:
const val EDIT_MODEL = "editModel"
const val EDIT_MODEL_ID = "editModelId"
open class EditServerFragment : Fragment()
private var _viewBinding: FragmentEditServerBinding? = null
private val viewBinding get() = _viewBinding!!
private val repository: ServersRepository by myApp.kodein.instance()
private var serverFormViewModel = ServerFormViewModel()
private var serverId: Long = 0
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View?
_viewBinding = FragmentEditServerBinding.inflate(inflater, container, false)
val view = viewBinding.root
val binding : FragmentEditServerBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_edit_server, container, false)
(Error here ->)**binding.item** = serverFormViewModel
// Dispatcher Back Step to Main
activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true)
override fun handleOnBackPressed()
toMain()
)
if (arguments?.getLong("ID") != null)
serverId = arguments?.getLong("ID")!!
// Set title
if (activity is AppCompatActivity)
(activity as AppCompatActivity).supportActionBar?.title = getString(R.string.edit_server)
if (serverId > 0)
lifecycleScope.launch
viewBinding.progressBar.visibility = View.VISIBLE
repository.get(serverId).let server ->
serverFormViewModel.setForm(server)
.also
viewBinding.progressBar.visibility = View.GONE
(Error here ->)**binding.item** = serverFormViewModel
viewBinding.cancelBtn.setOnClickListener
toMain()
viewBinding.saveBtn.setOnClickListener
if (serverFormViewModel.isFormValid())
lifecycleScope.launch
saveRecord(serverFormViewModel)
requireActivity().run
startActivity(Intent(this, MainActivity::class.java))
finish()
.also
toMain()
else
Utils.snackMsg(view, getString(R.string.error_empty_field))
println("EMPTY")
return viewBinding.root
override fun onSaveInstanceState(outState: Bundle)
super.onSaveInstanceState(outState)
outState.putLong(EDIT_MODEL_ID, serverId)
outState.putParcelable(EDIT_MODEL, serverFormViewModel.getModel())
override fun onViewStateRestored(savedInstanceState: Bundle?)
super.onViewStateRestored(savedInstanceState)
if (savedInstanceState != null)
serverId = savedInstanceState.getLong(EDIT_MODEL_ID)
serverFormViewModel.setForm(savedInstanceState.getParcelable(EDIT_MODEL)!!)
private fun saveRecord(viewModel: ServerFormViewModel)
viewBinding.progressBar.visibility = View.VISIBLE
try
repository.save(serverId, viewModel.getModel(serverId))
toMain()
catch (e: Exception)
view?.let Utils.snackMsg(it, e.message.toString())
finally
viewBinding.progressBar.visibility = View.GONE
private fun toMain()
requireActivity().run
startActivity(Intent(this, MainActivity::class.java))
finish()
布局:
<?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="item"
type="com.rompos.activator.kmm.shared.model.ServerFormViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/editView"
android:layout_
android:layout_
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputLayout
android:layout_
android:layout_
android:hint="@string/server_title"
app:endIconMode="clear_text"
tools:layout_editor_absoluteY="8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/serverTitle"
android:layout_
android:layout_
android:singleLine="true"
android:text="@=item.title" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_
android:layout_
android:hint="@string/server_url"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/serverUrl"
android:layout_
android:layout_
android:inputType="textUri"
android:singleLine="true"
android:text="@=item.url" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_
android:layout_
android:hint="@string/server_token"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/serverToken"
android:layout_
android:layout_
android:singleLine="true"
android:text="@=item.token" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_
android:layout_
android:layout_weight="1"
android:gravity="center|bottom"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/cancelBtn"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_
android:layout_
android:text="@string/cancel_btn"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/saveBtn"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/saveBtn"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_
android:layout_
android:text="@string/save_btn"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/progressBar"
android:layout_
android:layout_
android:background="#68898989"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_
android:layout_
android:backgroundTintMode="add"
android:progressBackgroundTintMode="multiply"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
视图模型:
class ServerFormViewModel
private var serverModel = ServerViewModel()
fun setForm(server: Server)
serverModel.setModel(server)
fun setForm(viewModel: ServerViewModel)
serverModel = viewModel
fun getTitle() : String
return serverModel.title ?: ""
fun setTitle(value: String)
serverModel.title = value
fun getUrl() : String
return serverModel.url ?: ""
fun setUrl(value: String)
serverModel.url = value
fun getToken() : String
return serverModel.token ?: ""
fun setToken(value: String)
serverModel.token = value
fun isFormValid() : Boolean
return !serverModel.title.isNullOrEmpty() and !serverModel.url.isNullOrEmpty() and !serverModel.token.isNullOrEmpty()
fun getModel(id: Long?) : Server
return Server(id!!, serverModel.title, serverModel.url, serverModel.token)
fun getModel() : ServerViewModel
return serverModel
Git 上的这个项目: https://github.com/Diy2210/com.rompos.activator.kmm
【问题讨论】:
【参考方案1】:我认为您需要在 onViewCreated
方法中绑定您的 ViewModel。
【讨论】:
以上是关于使用 Kotlin Multiplatform Mobile (KMM) 的多平台应用程序中的 DataBinding 错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kotlin/Multiplatform 项目中使用 .klib 库
如何使用 Kotlin-Multiplatform 在 iOS 应用程序的后台线程中运行任务?
如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟
在 Kotlin Multiplatform 中使用 Swift 协议默认实现