【问题标题】:Kotlin Android - Unable to get @BindingAdapter to workKotlin Android - 无法让@BindingAdapter 工作
【发布时间】:2018-04-14 07:06:22
【问题描述】:

我在尝试使用@BindingAdapter 时不断收到绑定错误。尝试 3 天并关注有关此主题的大量在线文章,但仍然收到以下错误。

@BindingAdapter("focusableColor")
fun setFocusableColor(v:CardView,  color:Int) {
    println("hello")
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          val binding:ActivityMainBinding  = 
              DataBindingUtil.setContentView(this,R.layout.activity_main)
          etc...
    }



In current_task_layout.xml

<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
            <variable name="task" type="com.edenhan.simplytask.Task">
            </variable>
    </data>

<android.support.v7.widget.CardView
  android:id="@+id/card_view">
  .....
  focusableColor="@{1}"/>

遇到错误:

发现数据绑定错误。

****/ 数据绑定错误 ****msg: 找不到参数类型为 int 的属性“focusableColor”的设置器 android.support.v7.widget.CardView。 文件:D:\…….\app\src\main\res\layout\current_task_layout.xml

【问题讨论】:

    标签: android binding kotlin


    【解决方案1】:

    您是否尝试过将绑定移出伴随对象? 您应该将它放在一个 kotlin 文件中,并使其成为顶级函数。例如:

    Bindings.kt

    @BindingAdapter("focusableColor")
    fun setFocusableColor(v:CardView,  color:Int) {..}
    

    并将绑定xml放到app命名空间中

    另外,请参阅Kotlin custom attribute databinding

    编辑:完整示例

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
    
    @BindingAdapter("focusableColor")
    fun setColor(card: CardView, @ColorInt color: Int) {
        // or whatever
        card.setBackgroundColor(color)
    }
    

    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"
        >
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
    
            <android.support.v7.widget.CardView
                android:id="@+id/card"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:focusableColor="@{1}"/>
        </android.support.constraint.ConstraintLayout>
    </layout>
    

    【讨论】:

    • 嗨。谢谢你的建议。我刚刚通过将它移到 Activity 类之外但在同一个 kotlin 文件中来尝试你的建议。但仍然没有解决问题。
    • 哦,可以在xml中添加app命名空间吗? app:focusableColor
    • 嗨,我补充说,但仍然是同样的错误。发现数据绑定错误。 ****/ 数据绑定错误 ****msg:Cannot find the setter for attribute ‘app:focusableColor’ with ......
    • 你用&lt;layout&gt;&lt;/layout&gt;包裹你的布局吗?我刚刚编辑了我的答案。该设置适用于我,经过测试
    • 但我观察到,即使你将顶级函数转换为一个类,并在函数顶部添加 JvmStatic 和 BindingAdapter 注释,它也可以工作!
    【解决方案2】:

    下面定义了使用 BindingAdapter 和 Kotlin 加载图像的完整代码

    ImageLoader.kt

    import android.widget.ImageView
    import androidx.databinding.BindingAdapter
    import androidx.databinding.ObservableField
    
    class ImageLoader {
    
        val imageResource = ObservableField(R.drawable.ic_launcher_background)
    
        companion object {
            @JvmStatic
            @BindingAdapter("android:src")
            fun setImage(imageView: ImageView, imageRes: Int) {
                imageView.setImageResource(imageRes)
            }
        }
    }
    

    activity_home.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">
        <data>
            <variable name="imageLoader" type="com.sample.testdemo.ImageLoader"/>
        </data>
        <RelativeLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
            <ImageView android:layout_width="wrap_content"
                       android:layout_height="wrap_content"
                       android:contentDescription="@string/app_name"
                       android:src="@{imageLoader.imageResource}"
                       android:layout_centerInParent="true"/>
        </RelativeLayout>
    </layout>
    

    HomeActivity.kt

    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import androidx.databinding.DataBindingUtil
    import com.sample.testdemo.databinding.ActivityHomeBinding
    
    class HomeActivity : AppCompatActivity() {
    
        lateinit var binding: ActivityHomeBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            binding = DataBindingUtil.setContentView(this,  R.layout.activity_home)
    
            binding.imageLoader = ImageLoader()
        }
    }
    

    注意:不要忘记在应用级别 build.gradle 的顶部添加以下行

    apply plugin: 'kotlin-kapt'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多