Библиотека мобильного разработчика | Android, iOS, Swift, Retrofit, Moshi, Chuck
9.62K subscribers
1.64K photos
80 videos
52 files
4.45K links
Все самое полезное для мобильного разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a4adec1b17b35b6c0d8389
Download Telegram
👾 Функции высшего порядка

Функции высшего порядка в Kotlin — это функции, которые принимают другие функции в качестве аргументов и/или возвращают функции в качестве результата. Эти принимаемые и возвращаемые функции обычно являются лямбда-выражениями.

Функции высшего порядка являются основой концепции функционального программирования.

👉 Читать подробнее

#kotlin
4👍1
🚙 Kotlin Coroutines под капотом

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

В этой статье автор разбирает две базовые концепции, на основе которых строится Structured Concurrency — CoroutineContext и CoroutineScope.

👉 Читать статью

#новость #android #kotlin
2
👾 Почему reified возможно использовать только с inline-функциями

Ключевое слово reified используется только с inline-функциями, т.к. оно позволяет получить доступ к информации о типе-параметре на этапе выполнения программы, что невозможно для обычных (non-inline) функций.

inline-функции в Kotlin позволяют копировать тело функции непосредственно в вызывающий код. Это позволяет избежать накладных расходов на создание объектов и вызовы функций при каждом вызове.

Именно reified в комбинации с inline позволяет сохранить информацию о типе-параметре и передать ее внутрь функции в рантайме, что было бы невозможно без inline.

Также стоит отметить, что ключевое слово reified можно применять только с обобщенными типами (дженериками).

#kotlin
5
👾 Конструкторы в Kotlin

Свойств у класса может быть столько, сколько ему нужно. Но все они должны быть инициализированы при создании экземпляра этого класса. Поэтому для удобства был придуман конструктор — специальный блок кода, который вызывается при создании экземпляра класса. Ему передаются необходимые значения, которые потом используются для инициализации свойств.

Класс в Kotlin может иметь основной конструктор (primary) и один или более вторичных конструкторов (secondary). У класса может и не быть конструктора, но Kotlin всё равно автоматически сгенерирует основной конструктор по умолчанию (без параметров).

👉 Подробнее в статье

#kotlin
🥰4
🗺️ Pисуем аватарки на карте

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

В статье автор рассматривает, как загрузить изображение через Coil и отобразить его на карте при помощи SDK для Yandex MapKit.

👉 Читать статью

#новость #kotlin
🥰51
🎮 Свойства, методы get и set

Свойства класса — это переменные, которые хранят состояние объекта класса. Как и любая переменная, свойство может иметь тип, имя и значение.

В классе можно объявить свойства с помощью ключевого слова var или val. Свойства, объявленные с var, могут быть изменены после их инициализации, а свойства, объявленные с val, только для чтения.

class Person {
var name: String = ""
val age: Int = 0
}


При создании своего класса мы хотим сами управлять его свойствами, контролируя то, какие данные могут быть предоставлены или перезаписаны. С этой целью создаются get и set методы (геттеры и сеттеры). Цель get-метода — вернуть значение, а set-метода — записать полученное значение в свойство класса.

var name: String = ""
get() = field.toUpperCase()
set(value) {
field = "Name: $value"
}


В данном примере свойство name имеет тип String и начальное значение пустой строки. Геттер возвращает значение свойства, преобразованное к верхнему регистру. Сеттер устанавливает значение свойства с добавлением префикса "Name: " перед переданным значением. Слово field используется для обращения к текущему значению свойства.

Если get и set методы не были созданы вручную, то для таких свойств Kotlin незаметно сам их генерирует. При этом для свойства, объявленного с val, генерируется get-метод, а для свойства, объявленного с varи get, и set методы.

🐸 Библиотека мобильного разработчика

#буст #JuniorKit #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
🔍 Сompanion object (также Singleton)

Объекты можно объявлять внутри класса, при этом нет каких-либо ограничений по их количеству. Но только один объект можно пометить ключевым словом companion object в рамках одного класса.

Синглтон-свойство companion object достигается за счет того, что он создается внутри класса в качестве статического поля. Он будет инициализирован при первом обращении к нему или при создании первого экземпляра класса, в котором он объявлен.

Важно отметить, что companion object будет инициализирован первым, а затем уже будет создан экземпляр класса:

class MyClass {
init {
// Выполняется всегда после инициализации companion object
}

companion object {
init {
// Выполняется всегда перед блоком init содержащего класса
}
}
}

val myClass = MyClass()


Такому объекту можно не указывать свое имя, и обращаться к методам и свойствам объекта через имя содержащего его класса без явного указания имени объекта.

class SomeClass {

companion object {
fun create()
}
}

val someClass = SomeClass.create()


Компилируется в public static final class на Java. Работает подобно ключевому слову static в Java.

🐸 Библиотека мобильного разработчика

#буст #MiddlePath #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👏3
📌 Ключевое слово reified

reified — это ключевое слово, которое может быть использовано только в inline-функциях. reified позволяет получить информацию о типе generic-параметра во время выполнения программы. В обычном случае, информация о типах стирается и недоступна во время выполнения, но с помощью reified можно сохранять эту информацию и использовать в других частях приложения.

Несколько простых примеров применения:

1. Получить доступ к типу параметра во время выполнения

fun main() {
printType<String>() // String
printType<Int>() // Int
}

private inline fun <reified T> printType() {
println(T::class.simpleName)
}


В этом примере мы определяем функцию printType() с типовым параметром T, который мы указываем с помощью reified. Внутри функции мы можем получить тип T во время выполнения, используя T::class. Затем выводим название типа на экран с помощью simpleName. Когда мы вызываем функцию printType() с типом String или Int, она выводит соответствующий тип на экран.

2. reified вместе с is для проверки типа аргумента во время выполнения

fun main() {
println(isOfType<Int>(1)) // true
println(isOfType<Int>("Hello")) // false
}

private inline fun <reified T> isOfType(value: Any): Boolean {
return value is T
}


Здесь мы определяем функцию isOfType(), которая принимает значение типа Any и возвращает true, если оно является типом T. Мы используем reified, чтобы получить доступ к типу T во время выполнения. Затем мы используем оператор is для проверки типа значения и возвращаем соответствующее boolean значение.

3. Получить список элементов перечисления

enum class Color { RED, GREEN, BLUE }

fun main() {
printEnumValues<Color>() // RED, GREEN, BLUE
}

private inline fun <reified T : Enum<T>> printEnumValues() {
enumValues<T>().forEach { value ->
println(value)
}
}


Определяем функцию printEnumValues(), которая выводит список элементов перечисления типа T. Мы применяем reified, чтобы получить доступ к типу T во время выполнения. Затем используем enumValues<T>(), чтобы получить список всех значений перечисления типа T. Внутри цикла выводим каждое значение на экран. Когда мы вызываем функцию printEnumValues() с типом Color, она выводит "RED", "GREEN" и "BLUE" в консоль.

🐸 Библиотека мобильного разработчика

#буст #JuniorKit #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🔴 Индикатор пульса в Jetpack Compose

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

Вот полная составная функция, которая отображает индикатор пульса:

@Composable
закрытый метод PulseIndicator(
@DrawableRes значок: Int,
модификатор: Modifier = Modifier
) {
val periodMs = 3600L
val offsetsMs = longArrayOf(0L, 1200L, 2400L)

val startNs = запомнить { System.nanoTime() }
var frameTimeNs by запомнить { mutableLongStateOf(startNs) }

LaunchedEffect(Единица измерения) {
while (true) {
withFrameNanos { now -> frameTimeNs = now }
}
}

(offsetMs: Long)фазафункция: число с плавающей запятой {
val elapsedMs = (frameTimeNs - startNs) / 1_000_000L + offsetMs
return ((elapsedMs % periodMs).toFloat() / periodMs.toFloat())
}

Box(modifier.size(80.dp), contentAlignment = Alignment.Center) {
(p:
Float )Кольцофункция@Composable = Box(
Модификатор
.matchParentSize()
.graphicsLayer {
scaleX = 1f + 0,8f * p
scaleY = 1f + 0,8f * p
alpha = 1f - p
}
.border(1,5.dp, Color.White.copy(alpha = 0,9f), CircleShape)
)

Кольцо(фаза(смещения[0]))
Кольцо(фаза(смещения[1]))
Кольцо(фаза(смещения[2]))

Box(
Modifier
.size(80.dp)
.background(Color.White, CircleShape),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(icon),
contentDescription = null,
modifier = Modifier.size(32.dp)
)
}
}
}


Как это работает

Хронометраж анимации

Компонуемый элемент использует withFrameNanos внутри LaunchedEffect. Это позволяет получить доступ к текущей временной метке кадра и обеспечивает плавность анимации, пока компонуемый элемент находится на экране. Когда компонуемый элемент покидает композицию, сопрограмма автоматически отменяется.

Расчет фазы

Функция phase(offsetMs) преобразует прошедшее время в значение между 0f и 1f. Каждое кольцо смещено (0, 1200, 2400 мс), поэтому они расширяются в разные моменты. Это создаёт иллюзию непрерывных волн.

Рендеринг кольца

Каждое кольцо изображается в виде Box с круглой рамкой. Его размер и непрозрачность изменяются с помощью graphicsLayer:

🔘 scaleX и scaleY постепенно увеличиваются от 1f до 1.8f.
🔘 alpha плавно переходит от 1f к 0f.

Вместе они образуют расширяющийся, затухающий круг.

Значок ядра

В центре находится сплошной белый круг с указанным значком (например, с меткой местоположения). Он служит статичной точкой привязки, в то время как анимированные кольца расходятся в стороны.

🐸 Библиотека мобильного разработчика

#PixelPerfect #MiddlePath #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4😁4👾1