10 个对 Android 开发者有用的 Kotlin 扩展函数 #2

10 个对 Android 开发者有用的 Kotlin 扩展函数 #2

通过出色的 Kotlin 扩展提高您的工作效率
logo

EditText

通过EditText的“text”属性,您可以快速获取EditText中的文本。但是,这个文本是“可编辑”的,因此每次都需要将其转换为字符串才能获得EditText的准确值。但好消息是,您可以使用下面列出的扩展属性轻松获取EditText的值。

import android.widget.EditText

val EditText.value
    get() = text?.toString() ?: ""

用法

val name = etName.value

startActivity

Start Activity 是转换到另一个 Activity 的常用方法。您必须首先解决目标活动的意图。但是,通过使用此扩展功能,您可以消除意图创建部分。

您还可以自定义传递一些数据和其他内容的意图。如果需要,它还可以终止当前的呼叫活动。看看下面的例子。

import android.app.Activity
import android.content.Intent

fun Activity.startActivity(
    cls: Class<*>,
    finishCallingActivity: Boolean = true,
    block: (Intent.() -> Unit)? = null
) {
    
    
    val intent = Intent(this, cls)
    block?.invoke(intent)
    startActivity(intent)
    if (finishCallingActivity) finish()
}

用法

startActivity(MainActivity::class.java) // Without Intent modification
startActivity(MainActivity::class.java) {
    
    
    // You can access the intent object in this block
    putExtra("key", "value")
}

Check Network

如今,根据我们的要求、特性和功能,我们所有的应用程序都具有互联网连接。因此,您可能需要检查互联网连接是否可用。
因此,此扩展功能对于检查活动和片段中的互联网连接很有用。它很容易在 if 语句和范围内的其他位置使用。

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import androidx.fragment.app.Fragment

fun Context.isNetworkAvailable(): Boolean {
    
    
    val manager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val capabilities = manager.getNetworkCapabilities(manager.activeNetwork)
    return if (capabilities != null) {
    
    
        capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
    } else false
}

fun Fragment.isNetworkAvailable() = requireContext().isNetworkAvailable()

用法

if (isNetworkAvailable()) {
    
    
    // Called when network is available
} else {
    
    
    // Called when network not available
}

Check Permission

为了完成我们的用例,您有时可能需要获得任何许可才能玩游戏。因此,我们可能必须验证是否为我们的应用程序授予了权限。因此,下面的扩展函数对于确定是否已授予权限很有用。

import android.content.Context
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat

fun Context.isPermissionGranted(permission: String) = run {
    
    
    ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}

用法

if (isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION)) {
    
    
    // Block runs if permission is granted
} else {
    
    
    // Ask for permission
}

用法

if (isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION)) {
    
    
    // Block runs if permission is granted
} else {
    
    
    // Ask for permission
}

delete whitespaces

有时我们可能会从 Rest API 或其他一些数据源获得不切实际的文本数据。所以,如果你有多个空格并且你想删除它,那么我们可以使用removeDuplicateWhitespaces(),或者如果你想完全删除它,那么你可以使用removeAllWhitespaces()扩展函数。

fun String.removeAllWhitespaces(): String {
    
    
    return this.replace("\\s+".toRegex(), "")
}

fun String.removeDuplicateWhitespaces(): String {
    
    
    return this.replace("\\s+".toRegex(), " ")
}

用法

"Hello,     world!!!".removeAllWhitespaces() // Output: Hello,world!!!
"Hello,     world!!!".removeDuplicateWhitespaces() // Output: Hello, world!!!

toEditable()

可编辑是文本的界面,其内容和标记可以更改。如果你想将字符串转换为可编辑的,那么你必须处理一个可编辑的工厂实例。

现在,使用以下功能,您可以轻松删除样板代码。您可以在任何字符串函数中使用 toEditable()。并且,您可以使用它将文本分配给 EditText 字段。

import android.text.Editable

fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)

用法

etName.text = "First name".toEditable()

Screen Size

如果您正在处理基于某些状态或数据的动态视图布局,则可能需要使用设备屏幕尺寸。因此,将为此使用此扩展属性。它会给出设备的高度和宽度。您可以在活动范围内使用它或在其他地方使用上下文对象。

import android.content.Context
import android.graphics.Insets
import android.graphics.Rect
import android.os.Build
import android.util.DisplayMetrics
import android.util.Size
import android.view.WindowInsets
import android.view.WindowManager

val Context.screenSize: Size
    get() {
    
    
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager

        val size = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    
    
            val metrics = windowManager.currentWindowMetrics
            val windowInsets = metrics.windowInsets
            val insets: Insets = windowInsets.getInsetsIgnoringVisibility(
                WindowInsets.Type.navigationBars()
                        or WindowInsets.Type.displayCutout()
            )

            val insetsWidth: Int = insets.right + insets.left
            val insetsHeight: Int = insets.top + insets.bottom
            val bounds: Rect = metrics.bounds
            Size(
                bounds.width() - insetsWidth,
                bounds.height() - insetsHeight
            )
        } else {
    
    
            val displayMetrics = DisplayMetrics()
            windowManager.defaultDisplay?.getMetrics(displayMetrics)
            val height = displayMetrics.heightPixels
            val width = displayMetrics.widthPixels
            Size(width, height)
        }
        return size
    }

用法

val size = screenSize
val deviceHeight = size.height
val deviceWidth = size.width

System Service Managers

这些属性用于直接访问system manager而无需创建它的对象。您可以直接在活动中使用它,对于必须使用上下文的片段。请注意,下面列出的属性并非全部。但如果需要更多,您可以添加更多。

import android.app.DownloadManager
import android.app.NotificationManager
import android.content.Context
import android.net.ConnectivityManager
import android.view.WindowManager
import androidx.core.content.ContextCompat

val Context.windowManager
    get() = ContextCompat.getSystemService(this, WindowManager::class.java)

val Context.connectivityManager
    get() = ContextCompat.getSystemService(this, ConnectivityManager::class.java)

val Context.notificationManager
    get() = ContextCompat.getSystemService(this, NotificationManager::class.java)

val Context.downloadManager
    get() = ContextCompat.getSystemService(this, DownloadManager::class.java)

用法

val manager = downloadManager // In Activity
val manager = requireContext().downloadManager// In Fragment

Copy to clipboard

您可能偶尔需要将文本复制到剪贴板,以允许用户与其他应用共享文本。因此,您可以在字符串对象上使用下面列出的扩展属性,一切顺利。

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import androidx.core.content.ContextCompat

fun String.copyToClipboard(context: Context) {
    
    
    val clipboardManager = ContextCompat.getSystemService(context, ClipboardManager::class.java)
    val clip = ClipData.newPlainText("clipboard", this)
    clipboardManager?.setPrimaryClip(clip)
}

用法

"This is clipboard".copyToClipboard(context)

Boolean Expressions

布尔值,是每个程序员的必备需求。在您的编程生活中,您每天都必须使用布尔值。在 kotlin 中,您可能必须同时处理可空性和布尔值,在这种情况下您可以利用这些扩展。在这里,我们也使用了合约的概念来实现智能铸造。

@file:OptIn(ExperimentalContracts::class)

import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

fun Boolean?.isTrue(): Boolean {
    
    
    contract {
    
    
        returns(true) implies (this@isTrue != null)
    }
    return this == true
}

fun Boolean?.isFalse(): Boolean {
    
    
    contract {
    
    
        returns(true) implies (this@isFalse != null)
    }
    return this == false
}

val Boolean?.orTrue: Boolean
    get() = this ?: true

val Boolean?.orFalse: Boolean
    get() = this ?: false

用法

lateinit var any: Boolean? // Assume that, this property is already assigned
if (any.isTrue()) {
    
    
    // Run when any is true only
}
if (any.isFalse()) {
    
    
    // Run when any is false only
}
val any1: Boolean = any.orTrue // If any is null then any1 = true otherwise any1 = any
val any2: Boolean = any.orFalse // If any is null then any1 = false otherwise any1 = any

结论

在这篇博文中,我们探索了适用于 Android 开发人员的 Kotlin 扩展功能。这些扩展可以简化常见任务,例如处理字符串、处理日期和时间、管理网络等。它们可以节省时间和精力、减少错误并提高代码的整体质量。

猜你喜欢

转载自blog.csdn.net/u011897062/article/details/130881156