10 useful Kotlin extension functions for Android developers #2

10 useful Kotlin extension functions for Android developers #2

Boost your productivity with great Kotlin extensions
logo

EditText

Through the "text" property of EditText, you can quickly get the text in EditText. However, this text is "editable", so it needs to be converted to a string every time to get the exact value of the EditText. But the good news is that you can easily get the value of the EditText using the extension properties listed below.

import android.widget.EditText

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

usage

val name = etName.value

startActivity

Start Activity is a common way to transition to another Activity. You must first resolve the intent of the target activity. However, by using this extension functionality, you can eliminate the intent creation part.

You can also customize the intent to pass some data and other stuff. It can also terminate the current call activity if needed. Take a look at the example below.

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()
}

usage

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

Today, all our applications have internet connectivity as per our requirements, features and functionality. Therefore, you may need to check whether an internet connection is available.
So this extension feature is useful for checking internet connection in activities and fragments. It's easy to use in if statements and elsewhere in the scope.

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()

usage

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

Check Permission

In order to accomplish our use case, you may sometimes need to obtain any permission to play the game. Therefore, we may have to verify that permissions are granted for our application. Therefore, the extension function below is useful for determining whether a permission has been granted.

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
}

usage

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

usage

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

delete whitespaces

Sometimes we may get unrealistic text data from Rest API or some other data sources. So, if you have multiple spaces and you want to remove it then we can use removeDuplicateWhitespaces(), or if you want to remove it completely then you can use removeAllWhitespaces()the extension function.

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

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

usage

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

toEditable()

Editable is an interface to text whose content and markup can be changed. If you want to convert a string to editable then you have to deal with an editable factory instance.

Now, with the following functions, you can easily remove boilerplate code. You can use toEditable() with any string function. And, you can use it to assign text to EditText fields.

import android.text.Editable

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

usage

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

Screen Size

If you're dealing with dynamic view layouts based on some state or data, you may want to use device screen sizes. So this extended attribute will be used for this. It will give the height and width of the device. You can use it in activity scope or use context object elsewhere.

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
    }

usage

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

System Service Managers

These properties are used to directly access the system manager without creating its object. You can use it directly in activities, for fragments you have to use context. Note that the properties listed below are not exhaustive. But you can add more if you need more.

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)

usage

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

Copy to clipboard

You may occasionally need to copy text to the clipboard to allow users to share text with other applications. So you can use the extension properties listed below on your string objects and you're good to go.

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)
}

usage

"This is clipboard".copyToClipboard(context)

Boolean Expressions

Boolean values ​​are an essential requirement for every programmer. You have to use booleans every day in your programming life. In kotlin, you might have to deal with both nullability and booleans, in which case you can take advantage of these extensions. Here, we also use the concept of contracts to realize smart casting.

@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

usage

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

in conclusion

In this blog post, we explore the Kotlin extensions for Android developers. These extensions simplify common tasks such as manipulating strings, working with dates and times, managing networks, and more. They save time and effort, reduce errors, and improve the overall quality of your code.

Guess you like

Origin blog.csdn.net/u011897062/article/details/130881156