Kotlin | Вопросы собесов
2.56K subscribers
28 photos
966 links
Download Telegram
🤔 Как в Ретрофите добавить возможность возвращать типы Rxjava?

Чтобы Retrofit мог возвращать Observable, Single, Maybe или Flowable из RxJava, нужно добавить RxJava Adapter.

🚩Добавление зависимости

В build.gradle.kts (Kotlin DSL)
dependencies {
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0") // Адаптер для RxJava 3
implementation("io.reactivex.rxjava3:rxjava:3.1.8") // RxJava 3
}


🚩Подключение `RxJava3CallAdapterFactory`

Добавляем адаптер в Retrofit.Builder
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create()) // Преобразование JSON
.addCallAdapterFactory(RxJava3CallAdapterFactory.create()) // Поддержка RxJava
.build()


🚩Использование RxJava в API

Теперь можно возвращать RxJava-объекты вместо Call<>.
interface ApiService {
@GET("users/{id}")
fun getUser(@Path("id") userId: Int): Single<User>
}


Пример с Observable<> (несколько данных или обновления)
interface ApiService {
@GET("users")
fun getUsers(): Observable<List<User>>
}


Пример с Flowable<> (если нужен Backpressure)
interface ApiService {
@GET("posts")
fun getPosts(): Flowable<List<Post>>
}


🚩Подписка и обработка результата

Пример подписки в ViewModel (RxJava 3 + LiveData)
class UserViewModel(private val apiService: ApiService) : ViewModel() {

private val _userLiveData = MutableLiveData<User>()
val userLiveData: LiveData<User> = _userLiveData

fun fetchUser(userId: Int) {
apiService.getUser(userId)
.subscribeOn(Schedulers.io()) // Запрос в фоновом потоке
.observeOn(AndroidSchedulers.mainThread()) // Обновление UI в главном потоке
.subscribe({ user ->
_userLiveData.value = user
}, { error ->
Log.e("UserViewModel", "Ошибка загрузки", error)
})
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁2👍1
Forwarded from easyoffer
На easyoffer 2.0 появится:
Тренажер "Реальное собеседование"

🟠 Сценарии вопросов из реального собеседования
🟠Возможность подготовиться к собеседованию в конкретную компанию
🟠Итоговая статистика (прошёл/не прошёл)

Сценарий вопросов взят из реального собеседования. То есть вы тренируетесь на тех вопросах, которые действительно задавались в компании X.

Уже в начале следующей недели стартует краудфандинг кампания, чтобы ускорить разработку easyoffer 2.0. Все кто, поддержал проект на этом этапе смогу получить 1 год доступа к сайту по цене месячной подписки. Первые 150 донатеров получать особо-выгодную цену и бонус. Следите за стартом 👉 в этом телеграм канале, в нем информация о старте будет опубликована за 6 часов до официального начала.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что известно про Star Projection?

Star Projection (*) используется в Kotlin Generics, когда точный тип параметра неизвестен.
- List<*> означает List с элементами любого типа, но доступ к ним возможен только для чтения.
- Используется для работы с универсальными API, где нет строгой типизации (MutableList<out T>).
Применяется в коллекциях и функциях, работающих с неизвестными дженериками.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
🤔 Можно ли после by вызвать функцию или конструктор?

Нет, после by нельзя вызывать функции или конструкторы. by ожидает готовый объект, который реализует интерфейс или делегирует свойство.

🚩Что такое `by`?

В Kotlin by используется в двух случаях:
Делегирование интерфейсов (class A : Interface by obj)
Делегирование свойств (val x by lazy {})
Но by не может вызывать функции или конструкторы – ему нужен уже созданный объект.

🟠`by` и делегирование интерфейсов
Правильный код (делегируем готовый объект)
interface Printer {
fun printMessage()
}

class RealPrinter : Printer {
override fun printMessage() = println("Печать...")
}

// Делегируем готовый объект `RealPrinter()`
class MyClass : Printer by RealPrinter()

fun main() {
MyClass().printMessage() // Печать...
}


Ошибка, если после by вызвать конструктор
class MyClass : Printer by RealPrinter() //  Работает
class MyClass2 : Printer by RealPrinter() { } // Ошибка!


🟠`by` и делегирование свойств
Правильный код (by lazy)
val message: String by lazy { "Привет, мир!" }
println(message) // Привет, мир!


Ошибка, если после by вызвать функцию
val message: String by getMessage() //  Ошибка!

fun getMessage() = "Привет, мир!"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1🤯1
🤔 Что известно про Back Pressure?

Это механизм контроля потока данных, предотвращающий перегрузку потребителя (consumer), если источник (producer) отправляет данные слишком быстро.
В Kotlin Flow и Reactive Streams (RxJava, Project Reactor) есть стратегии управления Back Pressure:
- Buffer – накапливает данные в памяти.
- Drop – игнорирует избыточные элементы.
- Latest – хранит только последний элемент.
- Conflate – объединяет значения для уменьшения нагрузки.
Back Pressure нужен для стабильности и предотвращения утечек памяти в асинхронных потоках.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥21
🤔 Что при создании классов в Kotlin изменились по сравнению с Java?

При создании классов по сравнению с Java произошли несколько значительных изменений и упрощений. Kotlin предлагает более лаконичный и выразительный синтаксис, что делает код более читаемым и удобным.

🚩Объявление классов и конструкторов

В Kotlin объявление классов и их конструкторов значительно упрощено.
В Java
public class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}


В Kotlin
class Person(val name: String, val age: Int)


🟠Статические члены
В Java для объявления статических членов используется ключевое слово static. В Kotlin вместо этого используются companion object.
В Java
public class MyClass {
public static final String CONSTANT = "constant";

public static void staticMethod() {
// Some code
}
}


В Kotlin
class MyClass {
companion object {
const val CONSTANT = "constant"

@JvmStatic
fun staticMethod() {
// Some code
}
}
}


🟠Data классы
Kotlin предоставляет специальный тип классов — data классы, которые автоматически генерируют методы equals(), hashCode(), toString(), copy(), и componentN().
В Java
public class User {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public boolean equals(Object o) {
// Implementation
}

@Override
public int hashCode() {
// Implementation
}

@Override
public String toString() {
// Implementation
}
}


В Kotlin
data class User(val name: String, val age: Int)


🟠Свойства и методы доступа
В Kotlin свойства объявляются напрямую, и методы доступа (геттеры и сеттеры) генерируются автоматически.
В Java
public class Rectangle {
private int width;
private int height;

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}
}


В Kotlin
class Rectangle(var width: Int, var height: Int)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🔥2🤔1
Forwarded from easyoffer
На easyoffer 2.0 появится:
База тестовых заданий

🟠Тестовые задания для разных грейдов
🟠Фильтрация тестовых заданий по технологиям и компаниям

Когда я только начинал учиться на программиста, я постоянно выдумывал себе задачи для практики и тратил на это много времени. Но только в момент поиска работы я столкнулся с тестовыми заданиями, и понял насколько круто они прокачивают навыки. Нужно было еще на этапе обучения пробовать их делать. Все компании стараются составить тестовое задание "под себя", это дает большой выбор в тематике задач и технологий. На easyoffer 2.0 вы сможете отфильтровать тестовые задания по навыкам/грейдам и найти те, что подходят лично вам для практики.

В течение 1-2 дней я объявлю о краудфандинг кампании, чтобы ускорить разработку easyoffer 2.0. Все кто, поддержал проект на этом этапе смогу получить 1 год доступа к сайту по цене месячной подписки и смогут попасть на закрытое бета-тестирование. А первые 150 донатеров получать особо-выгодную цену и бонус.

🚀 Следите за стартом 👉 в этом телеграм канале, в нем информация о старте будет опубликована за 6 часов до официального начала.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Восьмая версия Java поддерживается всеми версиями Android?

Начиная с Android Nougat (API уровень 24), Android начал поддерживать некоторые особенности Java 8, включая лямбды и стримы. Для более ранних версий Android можно использовать инструменты, такие как Retrolambda или Android Studio's desugar, для поддержки некоторых особенностей Java 8.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
🤔 Что такое px, dp, sp?

В Android используются разные единицы измерения для работы с экраном, чтобы адаптировать UI под разные устройства.

🚩`px` (пиксели) – физические точки экрана

px (pixel) – это самая маленькая единица изображения на экране.
Не зависит от плотности экрана → на разных устройствах элементы могут выглядеть слишком маленькими или большими.
<TextView
android:layout_width="100px"
android:layout_height="50px"/>


🚩`dp` (density-independent pixels) – независимые от плотности пиксели

dp (density-independent pixel) – это абстрактная единица измерения, которая адаптируется под плотность экрана (dpi).
Рекомендуется для всех размеров UI, чтобы интерфейс выглядел одинаково на разных устройствах.
<TextView
android:layout_width="100dp"
android:layout_height="50dp"/>


Пример в Kotlin
val sizeInPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 100f, resources.displayMetrics
)


🚩`sp` (scale-independent pixels) – масштабируемые пиксели (для текста)

sp (scale-independent pixel) – как dp, но ещё учитывает настройки шрифта пользователя. Используется только для размеров шрифтов.
<TextView
android:text="Привет, мир!"
android:textSize="16sp"/>


Пример в Kotlin
val textSizeInPx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16f, resources.displayMetrics
)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Есть ли случаи, когда не получится отменить корутину?

Да, есть три основных случая:
1. Блокирующий код – если внутри корутины используется блокирующая операция (Thread.sleep(), while(true) {}), она не реагирует на отмену.
2. Отмена родительской корутины не отменяет launch(NonCancellable) – если корутина запущена с NonCancellable, она игнорирует отмену.
3. Отмена не срабатывает, если корутина не проверяет isActive или yield() – долгие вычисления без точек приостановки не дадут корутине завершиться.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
🤔 Как бы реализовал агрегацию на устройстве нескольких rss лент?

Если нужно собирать данные из нескольких RSS-источников, можно реализовать это так:

Загрузить данные из нескольких RSS-лент (через Retrofit, Jsoup, XmlPullParser).
Парсить XML и извлекать статьи.
Объединять данные в общий список (List<Article>).
Сортировать по дате.
Сохранять в БД (Room) для офлайн-доступа.
Показывать в RecyclerView или LazyColumn (Compose).

🚩Добавляем зависимости

В build.gradle.kts
dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0") // HTTP-клиент
implementation("com.squareup.retrofit2:converter-simplexml:2.9.0") // XML-парсер
implementation("org.jsoup:jsoup:1.16.1") // Альтернативный XML-парсер
implementation("androidx.room:room-runtime:2.6.1") // Room для кеша
kapt("androidx.room:room-compiler:2.6.1")
}


🚩Описываем модель данных (RSS-статья)

RSS-лента содержит заголовок, ссылку, дату и описание
@Root(name = "item", strict = false)
data class RssItem(
@field:Element(name = "title") var title: String = "",
@field:Element(name = "link") var link: String = "",
@field:Element(name = "pubDate", required = false) var pubDate: String = "",
@field:Element(name = "description", required = false) var description: String = ""
)


Создаём API для загрузки RSS (Retrofit + XML)
interface RssService {
@GET("rss.xml")
fun getFeed(): Call<RssFeed>
}

@Root(name = "rss", strict = false)
data class RssFeed(
@field:Element(name = "channel") var channel: RssChannel = RssChannel()
)

@Root(name = "channel", strict = false)
data class RssChannel(
@field:ElementList(entry = "item", inline = true) var items: List<RssItem> = listOf()
)


🚩Объединяем несколько RSS-лент

Создадим Repository, который загружает и объединяет данные:
class RssRepository(private val services: List<RssService>) {

fun fetchAllFeeds(): List<RssItem> {
val allItems = mutableListOf<RssItem>()

services.forEach { service ->
val response = service.getFeed().execute()
if (response.isSuccessful) {
response.body()?.channel?.items?.let { allItems.addAll(it) }
}
}

return allItems.sortedByDescending { parseDate(it.pubDate) }
}

private fun parseDate(dateString: String): Long {
return SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH)
.parse(dateString)?.time ?: 0
}
}


🚩Сохраняем в Room для офлайн-доступа

Создаём Entity для БД
@Entity
data class ArticleEntity(
@PrimaryKey val link: String,
val title: String,
val pubDate: Long,
val description: String
)


Создаём DAO
@Dao
interface RssDao {
@Query("SELECT * FROM ArticleEntity ORDER BY pubDate DESC")
fun getArticles(): LiveData<List<ArticleEntity>>

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertArticles(articles: List<ArticleEntity>)
}


Сохраняем в БД после загрузки
class RssRepository(private val dao: RssDao, private val services: List<RssService>) {

fun fetchAndCacheFeeds() {
val articles = fetchAllFeeds().map {
ArticleEntity(it.link, it.title, parseDate(it.pubDate), it.description)
}
dao.insertArticles(articles)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Forwarded from easyoffer
🎉 Краудфандинг easyoffer 2.0 стартовал!

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

🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)

Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer

📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Forwarded from easyoffer
Я поставил целью сбора скромные 300 тыс. рублей, но ребята, вы накидали больше млн. всего за 1 день. Это просто невероятно!

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

Краудфандинг будет продолжаться еще 31 день и все кто поддержать проект сейчас, до его выхода, смогут получить:

🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)

Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer

Огромное спасибо за вашу поддержку! 🤝
🤔 Что такое сборщик мусора?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 В какой момент генерируется код при использовании SQLite?

Код для работы с SQLite в Android не генерируется автоматически — разработчик сам пишет SQL-запросы и управляет БД.

Но если используется Room (ORM для SQLite), то код генерируется на этапе компиляции с помощью Annotation Processing (kapt) или KSP.

🚩Обычный SQLite – без генерации кода

Если используешь SQLiteOpenHelper, то код не генерируется, ты сам пишешь SQL-запросы:
class MyDatabaseHelper(context: Context) : SQLiteOpenHelper(context, "mydb", null, 1) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
}

override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS users")
onCreate(db)
}
}


🚩Room – код генерируется при компиляции

Если используешь Room, код автоматически генерируется во время компиляции с помощью Annotation Processing (kapt) или KSP.
Ты пишешь аннотации (@Entity, @Dao, @Database).
Room-аннотации анализируются при компиляции (kapt / KSP).
Генерируется SQL-код и DAO-методы.
@Entity
data class User(
@PrimaryKey val id: Int,
val name: String
)

@Dao
interface UserDao {
@Query("SELECT * FROM User")
fun getAllUsers(): List<User>

@Insert
fun insert(user: User)
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}


🚩Когда именно генерируется код Room?

Если используешь kapt (Annotation Processor) или KSP, то код генерируется во время компиляции.
dependencies {
implementation("androidx.room:room-runtime:2.6.1")
kapt("androidx.room:room-compiler:2.6.1") // Кодогенерация
}


Пример с KSP (быстрее kapt)
dependencies {
implementation("androidx.room:room-runtime:2.6.1")
ksp("androidx.room:room-compiler:2.6.1") // Кодогенерация
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что можно делать через Composer?

Это внутренний компонент Compose, отвечающий за управление состоянием и рендерингом. Через него Compose отслеживает изменения в UI и обновляет только те элементы, которые изменились. Он также управляет процессом "recomposition".


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
🤔 Как класс-наследник оперирует функционалом класса-родителя?

Класс-наследник в Kotlin получает доступ к функционалу родительского класса через:
Наследование (:) — доступ ко всем open методам и свойствам.
Ключевое слово super — вызов методов родителя.
Переопределение (override) — изменение поведения.

🚩Наследование: доступ к методам и свойствам

Класс-наследник получает доступ ко всем open методам и свойствам родителя.
open class Animal(val name: String) {
fun eat() {
println("$name ест")
}
}

class Dog(name: String) : Animal(name)

fun main() {
val dog = Dog("Шарик")
dog.eat() // Шарик ест (метод унаследован)
}


🚩`super` – вызов методов родителя

Пример
open class Animal {
open fun makeSound() {
println("Животное издаёт звук")
}
}

class Dog : Animal() {
override fun makeSound() {
super.makeSound() // Вызываем метод родителя
println("Гав-гав!")
}
}

fun main() {
val dog = Dog()
dog.makeSound()
}


Вывод
Животное издаёт звук
Гав-гав!


🚩Переопределение (`override`)

Класс-наследник может изменить поведение родительского метода.
open class Animal {
open fun move() {
println("Животное двигается")
}
}

class Bird : Animal() {
override fun move() {
println("Птица летит") // Переопределяем метод
}
}

fun main() {
val bird = Bird()
bird.move() // Птица летит
}


🚩Вызов конструктора родителя (`super`)

Пример
open class Animal(val name: String)

class Dog(name: String, val breed: String) : Animal(name) {
fun info() {
println("Имя: $name, Порода: $breed") // Используем `name` из родителя
}
}

fun main() {
val dog = Dog("Бобик", "Лабрадор")
dog.info() // Имя: Бобик, Порода: Лабрадор
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что такое dp?

dp (Density-independent Pixels) — это единица измерения в Android, используемая для создания адаптивных интерфейсов. Она масштабируется в зависимости от плотности экрана устройства, обеспечивая одинаковый визуальный размер элементов на разных экранах.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥2😁1
🤔 Опиши как лучше всего использовать модификаторы доступа в Java?

В Java есть 4 модификатора доступа, которые контролируют видимость полей, методов и классов:

🚩`private` – самый безопасный (использовать по умолчанию)

Поля почти всегда должны быть private, чтобы инкапсулировать данные. Методы тоже лучше делать private, если они не должны использоваться извне.
public class User {
private String name; // Доступен только внутри класса

public User(String name) {
this.name = name;
}

private void logUserAction() { // Только внутри класса
System.out.println(name + " совершил действие");
}
}


🚩`package-private` (без модификатора) – для классов внутри пакета

Используется, если класс не должен быть доступен за пределами пакета. Полезно для вспомогательных классов.
class FileHelper { //  Доступен только в этом пакете
static void readFile(String path) {
System.out.println("Читаем файл: " + path);
}
}


🚩`protected` – для наследников, но не для всех

protected лучше использовать только в abstract классах и для методов, которые должны быть переопределены. Не используй protected для полей → нарушает инкапсуляцию!
abstract class Animal {
protected void makeSound() { // Наследники могут переопределять
System.out.println("Какой-то звук");
}
}

class Dog extends Animal {
@Override
protected void makeSound() {
System.out.println("Гав-гав!");
}
}


🚩`public` – только если класс/метод нужен везде

Класс можно делать public, только если он должен быть доступен во всех пакетах. Не делай поля public → нарушает инкапсуляцию!
public class UserManager { //  Доступен везде
public void createUser() { // Можно вызывать в любом месте
System.out.println("Создание пользователя...");
}
}


🚩`final` и `static` – дополняем модификаторы

final class → класс нельзя наследовать.
final method → метод нельзя переопределить.
final field → переменная неизменяема (константа).
public final class MathUtils {
public static final double PI = 3.14159;
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что известно про stable?

Это аннотация в Compose, которая указывает, что объект стабилен и его свойства не изменяются спонтанно. Это помогает Compose эффективно определять, когда нужно перерисовывать UI, уменьшая количество лишних перерисовок.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🤔 Как сказать адаптеру перерисовать список, если какой-то элемент удалился?

Если удалился элемент из списка, нужно:
Удалить его из списка данных.
Сообщить Adapter, чтобы он перерисовал только изменённые элементы.

🚩Используем `notifyItemRemoved()` (лучший вариант)

Этот метод обновляет только удалённый элемент, сохраняя анимации.
fun removeItem(position: Int) {
itemList.removeAt(position) // Удаляем из списка данных
notifyItemRemoved(position) // Сообщаем адаптеру
notifyItemRangeChanged(position, itemList.size) // Обновляем индексы
}


🚩Если изменился весь список – `DiffUtil`

Если изменился несколько элементов, лучше использовать DiffUtil, чтобы обновить только нужные элементы.
class MyAdapter : ListAdapter<Item, MyViewHolder>(DIFF_CALLBACK) {

companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}

override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
}
}
}


Обновляем список через submitList()
fun removeItem(item: Item) {
val newList = currentList.toMutableList()
newList.remove(item)
submitList(newList) // `DiffUtil` сам вычислит, что обновить
}


🚩Полное обновление списка (`notifyDataSetChanged()`)

Использовать только если изменился весь список!
fun removeItem(position: Int) {
itemList.removeAt(position)
notifyDataSetChanged() // Перерисовывает весь список (медленно)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5