Site icon AppTractor

9 полезных функций расширения Kotlin

Kotlin — это мощный язык программирования, который предоставляет много функциональных возможностей из коробки. Однако истинная сила Kotlin заключается в его функциях расширения, которые позволяют разработчикам добавлять функциональность к существующим классам и объектам без создания подклассов или изменения исходного кода. Вот 10 полезных расширений Kotlin, которые сделают ваш код более лаконичным и читабельным.

withNotNull

Одна из распространенных проблем, с которой сталкиваются разработчики при работе с нулевыми значениями, — это проверка на null перед выполнением операций. Функция расширения withNotNull упрощает этот процесс, позволяя разработчикам выполнять блок кода только в том случае, если значение не является null.

inline fun <T : Any, R> T?.withNotNull(block: (T) -> R): R? {
    return this?.let(block)
}

Использование:

val nullableValue: String? = null
nullableValue.withNotNull { value ->
    // Code here will only be executed if nullableValue is not null
}

toLiveData

LiveData — это data holder класс, который учитывает жизненный цикл и может быть наблюдаем. Функция расширения toLiveData упрощает процесс преобразования Flow в LiveData.

fun <T> Flow<T>.toLiveData(): LiveData<T> {
    return liveData {
        collect {
            emit(it)
        }
    }
}

Использование:

val flow = flowOf("Hello", "World")
val liveData = flow.toLiveData()

notEmpty

Функция расширения notEmpty упрощает процесс проверки того, не пуста ли коллекция.

fun <T> Collection<T>?.notEmpty(): Boolean {
    return this != null && this.isNotEmpty()
}

Более лаконичный способ:

fun <T> Collection<T>?.notEmpty(): Boolean {
    return this?.isNotEmpty() == true
}

Использование:

val list: List<Int> = emptyList()
if (list.notEmpty()) {
    // Code here will only be executed if list is not empty
}

getOrThrow

Функция расширения getOrThrow упрощает процесс получения значения из карты и выбрасывает исключение, если ключ не найден.

fun <K, V> Map<K, V>.getOrThrow(key: K): V {
    return this[key] ?: throw NoSuchElementException("Key $key not found in map")
}

Использование:

val map = mapOf("key1" to "value1", "key2" to "value2")
val value = map.getOrThrow("key3")

toFormattedString

Функция расширения toFormattedString упрощает процесс форматирования чисел и дат.

fun Int.toFormattedString(): String {
    return NumberFormat.getInstance().format(this)
}

fun Long.toFormattedString(): String {
    return NumberFormat.getInstance().format(this)
}

fun Date.toFormattedString(): String {
    return SimpleDateFormat.getDateInstance().format(this)
}

Использование:

val number = 1000000
val formattedNumber = number.toFormattedString()

debounce

Debounce упрощает процесс задержки выполнения блока кода до тех пор, пока не пройдет определенное количество времени с момента последнего выполнения блока.

fun View.onClick(debounceDuration: Long = 300L, action: (View) -> Unit) {
    setOnClickListener(DebouncedOnClickListener(debounceDuration) {
        action(it)
    })
}

private class DebouncedOnClickListener(
    private val debounceDuration: Long,
    private val clickAction: (View) -> Unit
) : View.OnClickListener {

    private var lastClickTime: Long = 0

    override fun onClick(v: View) {
        val now = SystemClock.elapsedRealtime()
        if (now - lastClickTime >= debounceDuration) {
            lastClickTime = now
            clickAction(v)
        }
    }
}

Использование:

button.onClick(debounceDuration = 500L) {
    // Code here will only be executed if 500 milliseconds have passed since the last click
}

toBitmap

Функция расширения toBitmap упрощает процесс преобразования drawable в растровое изображение.

fun Drawable.toBitmap(): Bitmap {
    if (this is BitmapDrawable) {
        return bitmap
    }

    val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)

    return bitmap
}

Использование:

val drawable = ContextCompat.getDrawable(context, R.drawable.my_drawable)
val bitmap = drawable.toBitmap()

toUri

Функция упрощает процесс преобразования пути к файлу в Uri.

fun String.toUri(): Uri {
    return Uri.parse(this)
}

Использование:

val filePath = "/storage/emulated/0/Download/my_file.pdf"
val fileUri = filePath.toUri()

applyIf

ApplyIf упрощает процесс применения блока кода к объекту только при выполнении определенного условия.

inline fun <T> T.applyIf(condition: Boolean, block: T.() -> Unit): T {
    return if (condition) {
        this.apply(block)
    } else {
        this
    }
}

Использование:

val number = 5
val formattedNumber = number.applyIf(number > 10) {
    toFormattedString()
}

В заключение следует отметить, что функции расширения Kotlin могут стать мощным инструментом для упрощения кода и повышения его читабельности. Используя эти 10 полезных расширений, вы сможете сделать свой код более лаконичным, эффективным и удобным для сопровождения.

Источник

Exit mobile version