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