Kotlin合成在Adapter或ViewHolder中


84

我是科特林的新手。我发现并试图用合成的方法,而不是恼人的方法findViewById在我的Activity课,但我发现“如果我们想打电话查看合成属性(适配器类有用的),我们也应导入kotlinx.android.synthetic.main 。视图。*。” 但是我不知道它是如何工作的?有没有例子?


您可以查看此博客或本示例
Cabezas

Answers:


96

来自https://github.com/antoniolg/Kotlin-for-Android-Developers的简单示例

import kotlinx.android.synthetic.item_forecast.view.*

class ForecastListAdapter() : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        fun bindForecast(forecast: Forecast) {
            itemView.date.text = forecast.date.toDateString()
        }
    }
}

不用写

val view = itemView.findViewById(R.id.date) as TextView
view.text = forecast.date.toDateString()

只是

itemView.date.text = forecast.date.toDateString()

简单有效!


4
好的,这可能是一个愚蠢的问题,但是“ itemView”引用来自何处?
索洛·阿吉亚尔

4
没有用于视图扩展的缓存,因此应像在普通viewHolder中一样缓存对视图的引用。
Miha_x64

21
:不幸的是打电话来findViewById每个bind()的调用medium.com/proandroiddev/...
米格尔·贝尔特兰

2
@Mike自Kotlin 1.1.4起,所有视图都将被缓存。即使在ViewHolders中。您发布的文章也提到了这一点。
Stefan Medack '17

2
@StefanMedack我是本文的作者:)尽管我必须指出,它只是实验功能的一部分,需要手动启用。我还没有尝试过。
米格尔·贝尔特兰

37

Kotling 1.1.4淘汰

更多信息:https : //antonioleiva.com/kotlin-android-extensions/

您需要通过将以下代码添加到build.gradle来启用Kotlin Android扩展

apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
    experimental = true
}

自Kotlin发行新版本以来,Android扩展已合并了一些有趣的新功能:任何类中的缓存(有趣的是包括ViewHolder)

在ViewHolder(或任何自定义类)上使用它。请注意,此类应实现LayoutContainer接口:

class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), 
        LayoutContainer {

    fun bind(title: String) {
        itemTitle.text = "Hello Kotlin!"
    }
}

3
添加到此信息中:根据Kotlin 1.1.4,此功能是试验性的,需要在build.gradle文件中启用
Miguel Beltran

2
这个实验了吗?我想在生产代码中使用它
卡森·霍尔茨海默

@CarsonH​​olzheimer,此功能仍处于实验阶段
the_dani

似乎甚至无法使用1.3.21。我认为他们不会实施它
user924 '19

但我们可以使用containerView.itemTitle.text = "Hello Kotlin!",我认为就够了
user924 '19


8

尝试

class CustomViewModel(val baseView: View) {
    val firstName = baseView.firstName
    val lastName = baseView.lastName
}

视图对象公开视图参考:https : //discuss.kotlinlang.org/t/unable-to-use-kotlin-android-extension-in-adapter-class/2890


答案已经给出了stackoverflow.com/a/33428208/7767664为什么要重复它?
user924

@ user924。如果答案已经在另一个线程中,请审核并标记当前线程为重复线程,并添加对其他线程的引用
hyena

4

如果您使用的是最新版本l ;,则无需在其中添加实验性= true。

在项目级别的Gradle中

classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21'

在应用程式等级Gradle中

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' //These should be on the top of file.

并在依赖中..

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21'

并导入为

import kotlinx.android.synthetic.main.your_layout_file_name.view.*

和例子

import kotlinx.android.synthetic.main.item_animal.view.*

class AnimalVH(parent: ViewGroup, layoutID: Int) : BaseViewHolder<Animal>(parent, layoutID) {

    override fun bindData(animal: Animal) {
        itemView.tv_animal.text = animal.title
    }
}

BaseViewHolder在哪里

abstract class BaseViewHolder<T>(parent: ViewGroup, layoutID: Int) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context).inflate(layoutID, parent, false)
) {
    abstract fun bindData(model: T)
}

对此有官方确认吗?我相信使用.view.*导入会失败的目的,后退将是findViewById<>每次-一个ViewHolder劝阻的模式。
天网


1

这意味着您必须将这一行放在源文件的开头:

import kotlinx.android.synthetic.main.view.*

因此,现在findView(R.id.textView) as TextView您可以只写而不是例如textView。后者是位于包中的综合扩展属性kotlinx.android.synthetic.main.view,这就是为什么必须从中导入所有内容的原因。

官方网站上有一个教程,看看吧。


1
我看过了 如上所述,我已经为自己的活动做好了。但是,如何在BaseAdapter衍生产品中使用它呢?

1
好吧,基本上,您可以findViewById()在上调用方法View,例如holder.findViewById(R.id.name)。使用Kotlin Android扩展,您可以编写holder.name。假设此代码编写在getView()函数内部:val base = inflater.inflate(R.layout.list_item, parent, false) base.name.text = "John Smith"
yanex

但是,如果我必须使用多个具有不同布局的视图持有人,该怎么办?我如何用合成物实现呢?因为我们必须为每个布局使用特定的“合成链接”,所以我有几个具有相似ID的布局。
纳坦·鲁宾斯坦

0

仅供参考:对于视图查找,建议使用数据绑定而非合成。

来自Google在Reddit上的Android版DA的评论

嘿! Google的Android开发者倡导者!

我想在这里添加一些背景。从来没有刻意“推荐”具有综合视图的Kotlin扩展,但不应将其作为不使用它们的建议。如果它们正在为您工作,请随时在您的应用中继续使用它们!

我们一直在远离它们(例如,我们不在Udacity课程中教他们),因为它们公开了ID的全局名称空间,该名称空间与实际上并未夸大无效查找的布局无关的ID,仅是Kotlin,并且不当视图仅在某些配置中存在时,不会公开可空性。这些问题共同导致API增加Android应用程序的崩溃次数。

另一方面,它们确实提供了轻量级的API,可以帮助简化视图查找。在此空间中,还值得一看的是Data Binding,它也执行自动视图查找-并与LiveData集成以在数据更改时自动更新视图。

如今,在这个领域中有一些可行的选择:

建议使用数据绑定进行视图查找和绑定,但是与Android Kotlin扩展相比,它确实增加了一些开销。值得一看,看看这是否适合您的应用程序。数据绑定还允许您观察LiveData在数据更改时自动绑定视图。与Kotlin Extensions相比,它增加了视图查找和类型安全性的编译时检查。官方不建议您使用Android Kotlin扩展程序(这与针对它的建议不同)。它确实带有上述问题,因此对于我们的代码,我们不使用它们。Butter Knife是另一种非常流行的解决方案,适用于Kotlin和Java编程语言。在这里阅读评论 许多开发者对Kotlin Extensions感到很幸运。太好了-在寻找继续改进API的方式时,我们会牢记一些事情。如果您还没有看过数据绑定,那么一定要尝试一下。

顺便说一句,我们的内部代码样式指南不能直接在我们的代码库之外应用。例如,我们使用mPrefixVariables,但是没有理由每个应用程序都应该遵循这种风格。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.