4

所以我检查了谷歌的这个代码实验室来创建一个自定义视图RatioImageViewOnMeasure()它只是扩展 ImageView 并根据设备的视口的纵横比覆盖该方法。相同的代码是:

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>

然后在适配器中,我使用DataBinding以下内容更新视图:

override fun onBindViewHolder(holder: HomeItemHolder, position: Int) {
        holder.binding.apply {

              //loadImage() is an extension function added to ImageView class
              target.loadImage(UiUtil.getCustomUrl(photos[position].urls.fullImage, height, width))
       
            root.setOnClickListener {
                handleClick(position)
            }
        }
}

在构建过程中,它显示以下错误:

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

即在OnBindViewHolder()target.loadImage(...)中写入的行

此外,如果我不将 DataBinding 用于根布局,那么它可以正常工作。

所以问题是需要添加RatioImageView什么?为了使它与 DataBinding 一起工作,考虑到这里我不需要 XML 布局与 View 类相关联。

这是onCreateViewHolder()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeItemHolder {
        return HomeItemHolder(ItemPhotoListLayoutBinding.inflate(LayoutInflater.from(parent.context)))
}

下面是ViewHolder课程:

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

如果我的代码在这里遗漏了一些东西,这里也是回购:https ://github.com/prafullmishra/CustomImageView

4

3 回答 3

1

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

您的 XML 引用了该类 com.example.bindingcustomimageview.CustomImage.RatioImageView。在不了解更多信息的情况下,RatioView看起来它是CustomImagepackage的一个公共内部类com.example.bindingcustomimageview

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

为避免将来出现此类混淆,请勿使用大写名称命名您的包。

于 2020-02-22T01:20:44.170 回答
0

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

  1. <variable name="image" type="Drawable"/><data>标签内添加
  2. 包括属性的绑定表达式src例如android:id="@{image}"
  3. 尝试以下操作:

    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)
        }
    }
    
于 2020-02-10T23:20:23.320 回答
0

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

  1. 带 1 个参数的那个:RatioImageView(context)
  2. 一个有2个参数的:RatioImageView(context, attrs)
  3. 一个有3个参数的:RatioImageView(context, attrs, defStyleAttr)

虽然RatioImageView只有一个具有 3 个参数的实现ImageView(context, attrs, defStyleAttr). 这就是为什么你得到那个错误。您还需要定义其他 2 个构造函数。

于 2020-02-16T16:14:13.793 回答