Android 如何将自定义ImageView与数据绑定一起使用?

Android 如何将自定义ImageView与数据绑定一起使用?,android,kotlin,android-custom-view,android-databinding,android-jetpack,Android,Kotlin,Android Custom View,Android Databinding,Android Jetpack,因此,我选中此选项以创建自定义视图RatioImageView。它只是扩展ImageView,并根据设备视口的纵横比覆盖OnMeasure()方法。其代码为: class RatioImageView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ): ImageView(context, attrs, defStyleAttr

因此,我选中此选项以创建自定义视图
RatioImageView
。它只是扩展ImageView,并根据设备视口的纵横比覆盖
OnMeasure()
方法。其代码为:

class RatioImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
): ImageView(context, attrs, defStyleAttr) {

    private val VP_HEIGHT = Resources.getSystem().displayMetrics.heightPixels
    private val VP_WIDTH = Resources.getSystem().displayMetrics.widthPixels
    private val HWR: Float = VP_HEIGHT.toFloat()/VP_WIDTH.toFloat() //height to width ratio


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),(MeasureSpec.getSize(widthMeasureSpec)*HWR).toInt())
    }
}
然后我在ListItem视图中使用它作为:

<?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>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp">

        <com.example.myapp.RatioImageView
            android:id="@+id/target"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:contentDescription="image holder"
            android:scaleType="centerCrop"
            android:background="#757575"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="9:16" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
在构建过程中,它显示以下错误:

无法访问类“RatioImageView”。检查模块类路径是否缺少依赖项或存在冲突依赖项

i、 e.对于在OnBindViewHolder()中写入
target.loadImage(…)
的行

另外,如果我不对根布局使用数据绑定,那么它也可以正常工作

因此,问题是需要将什么添加到
RatioImageView
?为了使它能够与数据绑定一起工作,考虑到这里我不需要将XML布局与View类相关联

以下是
onCreateViewHolder()

下面是
ViewHolder
类:

inner class HomeItemHolder (val binding: ItemPhotoListLayoutBinding):
        RecyclerView.ViewHolder(binding.root) {
}

另外,这里还有一个repo,以防我的代码在这里遗漏了什么:

您试图将数据绑定到xml中的哪个属性? 也许您想将图像绑定到
android:src
属性? 在这种情况下:

  • 标记内添加
  • src
    属性包括一个属性,例如
    android:id=“@{image}”
  • 请尝试以下操作:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.binding.apply {
    
        this.image = loadImage(UiUtil.getCustomUrl(photos[position].urls.fullImage, height, width))
    
        root.setOnClickListener {
            handleClick(position)
        }
    }
    

  • 任何自定义视图都应至少具有3种不同类型的构造函数实现,您需要提供这些实现才能方便地访问它:

  • 带有1个参数的参数:
    RatioImageView(上下文)
  • 一个有两个参数:
    RatioImageView(context,attrs)
  • 一个有3个参数:
    RatioImageView(context,attrs,defStyleAttr)

  • RatioImageView
    只有一个带有3个参数的参数,实现了
    ImageView(context、attrs、defStyleAttr)
    。这就是为什么你会犯这样的错误。您还需要定义其他2个构造函数。

    我在您发布在Github上的代码示例中发现了问题。实际上,从您发布的代码片段中解决这个问题很棘手,但是错误正确地表明类名有问题

    您的XML引用了该类
    com.example.bindingcustomimageview.CustomImage.RatioImageView
    。在不知道更多信息的情况下,
    RatioView
    看起来像是包
    com.example.bindingcustomimageview
    中的
    CustomImage
    的公共内部类

    但事实并非如此。它是包
    com.example.bindingcustomimageview.CustomImage
    中的类
    RatioImageView
    (其中“CustomImage”是大写的包名)。通过将
    RatioImageView
    拖到与MainActivity相同的包中,您可以快速修复它,一切都将正常工作


    为了避免将来出现类似的混淆,请不要使用大写名称命名包。

    xml中的
    com.example.myapp.RatioImageView
    与类包名称类似吗?我没有发现任何问题。您能否添加有关
    适配器的更多详细信息,这是
    RatioImageView
    的完整实现吗?@narekhayerapetyanyes@Md.Asaduzzaman为了简洁起见,我省略了适配器的其余部分。主要逻辑仅限于此,它无法通过
    holder.binding
    访问
    target
    RatioImageView,这就是我想要解决的问题。您是如何在ViewHolder中初始化
    binding
    的?您能否使用
    onCreatedViewHolder
    实现显示您的
    ViewHolder
    ?我问,因为它适用于meNope,我不打算通过XMLHelp绑定任何属性,但我为构造函数值准备了默认值。使用Kotlin的构造函数重载,这相当于声明了3个构造函数,就像我们在Java中必须声明的那样!谢谢你救了我一天!(还有我的应用程序:P)
    inner class HomeItemHolder (val binding: ItemPhotoListLayoutBinding):
            RecyclerView.ViewHolder(binding.root) {
    }
    
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.binding.apply {
    
        this.image = loadImage(UiUtil.getCustomUrl(photos[position].urls.fullImage, height, width))
    
        root.setOnClickListener {
            handleClick(position)
        }
    }