Adapter 或 ViewHolder 中的 Kotlin 合成
Kotlin synthetic in Adapter or ViewHolder
我是科特林的新手。我发现并尝试在我的 Activity
class 中使用合成方法而不是烦人的方法 findViewById
,但我发现 "If we want to call the synthetic properties on View (useful in adapter classes), we should also import kotlinx.android.synthetic.main.view.*." 但我无法弄清楚它到底是怎么回事作品?有例子吗?
这意味着您必须将此行放在源文件的开头:
import kotlinx.android.synthetic.main.view.*
所以现在您可以只写 textView
而不是 findView(R.id.textView) as TextView
。后者是位于包 kotlinx.android.synthetic.main.view
中的合成扩展 属性,这就是为什么您必须从中导入所有内容的原因。
来自 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()
简单有效!
你需要
import kotlinx.android.synthetic.row_wall.view.*
后来的内容如下:
convertView.titleText.text = item.title
重点是view.*引入了View的扩展class.
科特林 1.1.4 出
更多信息:https://antonioleiva.com/kotlin-android-extensions/
您需要启用 Kotlin Android 扩展,方法是将其添加到您的 build.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
experimental = true
}
自从这个新版本的 Kotlin 以来,Android 扩展包含了一些有趣的新功能:在任何 class 中缓存(有趣的是包括 ViewHolder)
在 ViewHolder(或任何自定义 class)上使用它。请注意,此 class 应实现 LayoutContainer
接口:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!"
}
}
尝试
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
如果您使用的是最新版本 l;.您不必为其添加 experimental = 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)
}
仅供参考: 对于视图查找,建议使用数据绑定而不是合成。
Comment from a DA for Android from Google 在 Reddit 上
Hey! Developer Advocate for Android at Google here!
I wanted to add a bit of background here. Kotlin Extensions with
synthetic views was never intentionally “recommended” though that
shouldn’t be taken as a recommendation to not use them. If they're
working for you please feel free to continue using them in your app!
We’ve been shifting away from them (e.g. we don’t teach them in the
Udacity course) because they expose a global namespace of ids that’s
unrelated to the layout that’s actually inflated with no checks
against invalid lookups, are Kotlin only, and don't expose nullability
when views are only present in some configuration. All together, these
issues cause the API to increase number of crashes for Android apps.
On the other hand, they do offer a lightweight API that can help
simplify view lookups. In this space it's also worth taking a look at
Data Binding which also does automatic view lookups - as well as
integrates with LiveData to automatically update your views as data
changes.
Today, there's a few options in this space that work:
Data Binding is the recommendation for view lookup as well as binding,
but it does add a bit of overhead when compared to Android Kotlin
Extensions. It's worth taking a look to see if this is a good fit for
your app. Data Binding also allows you to observe LiveData to bind
views automatically when data changes. Compared to Kotlin Extensions,
it adds compile time checking of view lookups and type safety. Android
Kotlin Extensions is not officially recommended (which is not the same
as recommendation against). It does come with the issues mentioned
above, so for our code we're not using them. Butter Knife is another
solution that is extremely popular and works for both Kotlin and the
Java Programming Language. Reading through the comments here there's a
lot of developers that are having great luck with Kotlin Extensions.
That's great - and something we'll keep in mind as we look at ways to
continue improving our APIs. If you haven't taken a look at Data
Binding, definitely give it a shot.
As an aside, our internal code style guide is not intended to be
directly applied outside of our codebase. For example, we use
mPrefixVariables, but there's no reason that every app should follow
that style.
我是科特林的新手。我发现并尝试在我的 Activity
class 中使用合成方法而不是烦人的方法 findViewById
,但我发现 "If we want to call the synthetic properties on View (useful in adapter classes), we should also import kotlinx.android.synthetic.main.view.*." 但我无法弄清楚它到底是怎么回事作品?有例子吗?
这意味着您必须将此行放在源文件的开头:
import kotlinx.android.synthetic.main.view.*
所以现在您可以只写 textView
而不是 findView(R.id.textView) as TextView
。后者是位于包 kotlinx.android.synthetic.main.view
中的合成扩展 属性,这就是为什么您必须从中导入所有内容的原因。
来自 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()
简单有效!
你需要
import kotlinx.android.synthetic.row_wall.view.*
后来的内容如下:
convertView.titleText.text = item.title
重点是view.*引入了View的扩展class.
科特林 1.1.4 出
更多信息:https://antonioleiva.com/kotlin-android-extensions/
您需要启用 Kotlin Android 扩展,方法是将其添加到您的 build.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
experimental = true
}
自从这个新版本的 Kotlin 以来,Android 扩展包含了一些有趣的新功能:在任何 class 中缓存(有趣的是包括 ViewHolder)
在 ViewHolder(或任何自定义 class)上使用它。请注意,此 class 应实现 LayoutContainer
接口:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!"
}
}
尝试
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
如果您使用的是最新版本 l;.您不必为其添加 experimental = 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)
}
仅供参考: 对于视图查找,建议使用数据绑定而不是合成。
Comment from a DA for Android from Google 在 Reddit 上
Hey! Developer Advocate for Android at Google here!
I wanted to add a bit of background here. Kotlin Extensions with synthetic views was never intentionally “recommended” though that shouldn’t be taken as a recommendation to not use them. If they're working for you please feel free to continue using them in your app!
We’ve been shifting away from them (e.g. we don’t teach them in the Udacity course) because they expose a global namespace of ids that’s unrelated to the layout that’s actually inflated with no checks against invalid lookups, are Kotlin only, and don't expose nullability when views are only present in some configuration. All together, these issues cause the API to increase number of crashes for Android apps.
On the other hand, they do offer a lightweight API that can help simplify view lookups. In this space it's also worth taking a look at Data Binding which also does automatic view lookups - as well as integrates with LiveData to automatically update your views as data changes.
Today, there's a few options in this space that work:
Data Binding is the recommendation for view lookup as well as binding, but it does add a bit of overhead when compared to Android Kotlin Extensions. It's worth taking a look to see if this is a good fit for your app. Data Binding also allows you to observe LiveData to bind views automatically when data changes. Compared to Kotlin Extensions, it adds compile time checking of view lookups and type safety. Android Kotlin Extensions is not officially recommended (which is not the same as recommendation against). It does come with the issues mentioned above, so for our code we're not using them. Butter Knife is another solution that is extremely popular and works for both Kotlin and the Java Programming Language. Reading through the comments here there's a lot of developers that are having great luck with Kotlin Extensions. That's great - and something we'll keep in mind as we look at ways to continue improving our APIs. If you haven't taken a look at Data Binding, definitely give it a shot.
As an aside, our internal code style guide is not intended to be directly applied outside of our codebase. For example, we use mPrefixVariables, but there's no reason that every app should follow that style.