Airbnb Epoxy 中未显示简单的 TextView

Simple TextView not showing in Airbnb Epoxy

我正在尝试在回收视图中使用 epoxy 显示一个简单的文本视图,但它没有出现。我哪里做错了。

我期待这样的事情

但我得到的是这个

//build.gradle
    implementation "com.airbnb.android:epoxy:4.3.1"
    kapt "com.airbnb.android:epoxy-processor:4.3.1"

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val rv= findViewById<RecyclerView>(R.id.main_recyclerview)
        rv.adapter= MyController().adapter
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

MyController.kt

class MyController : Typed2EpoxyController<List<String>,Boolean>() {
    override fun buildModels(data1: List<String>, data2: Boolean) {
        MyTextViewModel_().id(1).titleText("first title")
        MyTextViewModel_().id(2).titleText("second title")
        MyTextViewModel_().id(3).titleText("third title")
    }
}

MyTextViewModel.kt

@EpoxyModelClass(layout = R.layout.textview_row)
abstract class MyTextViewModel(): EpoxyModelWithHolder<VH>() {
    @EpoxyAttribute
    var titleText: String = "Default Title Text"

    override fun bind(holder: VH) {
        super.bind(holder)
        holder.titleTextView.text= titleText
    }
    class VH : EpoxyHolder() {
        lateinit var titleTextView: TextView
        override fun bindView(itemView: View) {
            titleTextView= itemView.findViewById(R.id.title)
        }
    }
}

textview_row.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/title_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:text="SIMPLE TITLE"
        app:layout_constraintBaseline_toBaselineOf="@+id/more_textview"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/more_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="More"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

尝试将 textview_row ConstraintLayout 更改为固定大小的高度或 wrap_content 而不是 match_parent,因为您不希望每个项目占据整个屏幕 space.

它可以潜在地解释您现在正在经历的事情。

我发现了多个问题,解决方案在这里:

1 - 按照 Ilya Gazman 的建议首先修复 textview_row 高度

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/title_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:text="SIMPLE TITLE"
        app:layout_constraintBaseline_toBaselineOf="@+id/more_textview"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/more_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="More"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

2 - RecyclerView class 类型有问题,你应该使用 com.airbnb.epoxy.EpoxyRecyclerView

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.airbnb.epoxy.EpoxyRecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3 - 控制器初始化

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val rv = findViewById<EpoxyRecyclerView>(R.id.main_recyclerview)
        val controller  = MyController()
        controller.setData(listOf("test","test2", "test3"),true)
        rv.adapter = controller.adapter
    }
}

4 - 缺少控制器 addTo

class MyController : Typed2EpoxyController<List<String>,Boolean>() {
    override fun buildModels(data1: List<String>, data2: Boolean) {
       data1.forEachIndexed { index, s ->
           MyTextViewModel_().id(index).titleText(s).addTo(this)
       }
    }
}

5 - 错误的 findViewById 引用。在您的示例中,您使用的是 title.

@EpoxyModelClass(layout = R.layout.textview_row)
abstract class MyTextViewModel(): EpoxyModelWithHolder<MyTextViewModel.VH>() {
    @EpoxyAttribute
    var titleText: String = "Default Title Text"

    override fun bind(holder: VH) {
        super.bind(holder)
        holder.titleTextView.text= titleText
    }

    class VH : EpoxyHolder() {
        lateinit var titleTextView: TextView
        override fun bindView(itemView: View) {
            titleTextView = itemView.findViewById(R.id.title_textview)
        }
    }
} 

结果: