Kotlin 扩展函数 - 如何使其全局化?
Kotlin extension function - How to make it global?
我在 Android ViewGroup
class 上创建了一个 Kotlin 扩展函数,以便它可以更轻松地进行布局 inflation 调用。所以,这是我的分机:
fun ViewGroup.inflate(layoutRes: Int): View {
return LayoutInflater.from(context).inflate(layoutRes, this, false)
}
然后我可以像这样在适配器中使用它 class 来膨胀布局:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = parent.inflate(R.layout.view_item)
return ViewHolder(v)
}
我已经在我用于 RecyclerView 的适配器 class 中声明了这个扩展,这样它可以使 inflation 调用更容易。但我想要所有适配器,或者我应该说所有 ViewGroup
classes 都能看到这个扩展。我想要它永久。
它似乎只停留在我声明它的地方,而不是全局。我应该在哪里声明这个扩展,以便在我使用视图组时这个方法扩展可用?
I have declared this extension in the adapter class i am using for a recyclerview so that it can make inflation calls more easier.
像这样,它只能在适配器的上下文中使用class。
要么在包级别(顶级)声明它,要么考虑定义一个包含扩展名的对象:
object ViewGroupExt {
//extensions go here
}
现在在调用方,您需要将 ViewGroupExt
纳入范围:
with(ViewGroupExt){
//call extensions
}
与包级声明相比,它的优点是必须对其进行访问显式。
问题:
如果您在此处定义扩展函数 (1),它将在全局范围内可访问,但这种风格很糟糕,因为这是(特殊适配器)MyArrayAdapter
和 [= 的 class 文件15=] 用于整个项目。
如果您在此处定义扩展函数 (2),它将只能在 MyArrayAdapter
的上下文中访问。
// (1)
class MyArrayAdapter: ArrayAdapter<String> {
// (2)
}
我会做什么:
创建一个文件 Util.kt,仅包含用作实用程序的顶级声明。
这就是您的 Util.kt 文件的样子:
package com.yourpackagepath // package in which Utils.kt resides
// written with expression body, which makes it more concise
fun ViewGroup.inflate(layoutRes: Int) = LayoutInflater.from(getContext()).inflate(layoutRes, this, false)
通过这种方式,扩展在整个项目范围内都可用,而且它是一种很好的风格,因为 Util.kt 意味着可以在任何地方使用的全局实用程序。
你可以这样称呼它:
val v = parent.inflate(R.layout.view_item)
如果不在同一个包中使用,可以这样导入:
import com.yourpackagepath.inflate
您可以通过在对象 class 中声明来使扩展功能全局化,如下所示:
object ViewExtension{
fun Spinner.validate(): Boolean {
if(!this.isSelected){
this.setSpinnerHint(this.context.getString(R.string.please_select))
return false
}
return true
}
fun TextInputLayout.validate(): Boolean{
if(TextUtils.isEmpty(editText?.text)){
this.error = this.context.getString(R.string.required)
return false
}
return true
}
}
如何使用扩展功能
fun validateFields(): Boolean{
var allSelected = true
textInput.validate().apply {
if(!this)
allSelected = false
}
spinner.validate().apply {
if(!this)
allSelected = false
}
}
我们还需要在使用之前导入验证方法 any class :
import com.example.ViewExtension.validate
我在 Android ViewGroup
class 上创建了一个 Kotlin 扩展函数,以便它可以更轻松地进行布局 inflation 调用。所以,这是我的分机:
fun ViewGroup.inflate(layoutRes: Int): View {
return LayoutInflater.from(context).inflate(layoutRes, this, false)
}
然后我可以像这样在适配器中使用它 class 来膨胀布局:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = parent.inflate(R.layout.view_item)
return ViewHolder(v)
}
我已经在我用于 RecyclerView 的适配器 class 中声明了这个扩展,这样它可以使 inflation 调用更容易。但我想要所有适配器,或者我应该说所有 ViewGroup
classes 都能看到这个扩展。我想要它永久。
它似乎只停留在我声明它的地方,而不是全局。我应该在哪里声明这个扩展,以便在我使用视图组时这个方法扩展可用?
I have declared this extension in the adapter class i am using for a recyclerview so that it can make inflation calls more easier.
像这样,它只能在适配器的上下文中使用class。
要么在包级别(顶级)声明它,要么考虑定义一个包含扩展名的对象:
object ViewGroupExt {
//extensions go here
}
现在在调用方,您需要将 ViewGroupExt
纳入范围:
with(ViewGroupExt){
//call extensions
}
与包级声明相比,它的优点是必须对其进行访问显式。
问题:
如果您在此处定义扩展函数 (1),它将在全局范围内可访问,但这种风格很糟糕,因为这是(特殊适配器)MyArrayAdapter
和 [= 的 class 文件15=] 用于整个项目。
如果您在此处定义扩展函数 (2),它将只能在 MyArrayAdapter
的上下文中访问。
// (1)
class MyArrayAdapter: ArrayAdapter<String> {
// (2)
}
我会做什么:
创建一个文件 Util.kt,仅包含用作实用程序的顶级声明。
这就是您的 Util.kt 文件的样子:
package com.yourpackagepath // package in which Utils.kt resides
// written with expression body, which makes it more concise
fun ViewGroup.inflate(layoutRes: Int) = LayoutInflater.from(getContext()).inflate(layoutRes, this, false)
通过这种方式,扩展在整个项目范围内都可用,而且它是一种很好的风格,因为 Util.kt 意味着可以在任何地方使用的全局实用程序。
你可以这样称呼它:
val v = parent.inflate(R.layout.view_item)
如果不在同一个包中使用,可以这样导入:
import com.yourpackagepath.inflate
您可以通过在对象 class 中声明来使扩展功能全局化,如下所示:
object ViewExtension{
fun Spinner.validate(): Boolean {
if(!this.isSelected){
this.setSpinnerHint(this.context.getString(R.string.please_select))
return false
}
return true
}
fun TextInputLayout.validate(): Boolean{
if(TextUtils.isEmpty(editText?.text)){
this.error = this.context.getString(R.string.required)
return false
}
return true
}
}
如何使用扩展功能
fun validateFields(): Boolean{
var allSelected = true
textInput.validate().apply {
if(!this)
allSelected = false
}
spinner.validate().apply {
if(!this)
allSelected = false
}
}
我们还需要在使用之前导入验证方法 any class :
import com.example.ViewExtension.validate