kotlin 81 lines · 1 tab

LiveData transformations and mediators

Alex Chen Jan 2026
1 tab
package com.example.myapp.ui

import androidx.lifecycle.*
import kotlinx.coroutines.launch

class UserViewModel(
    private val userRepository: UserRepository
) : ViewModel() {

    private val _userId = MutableLiveData<Int>()

    // Transform user ID to full user object
    val user: LiveData<User?> = _userId.switchMap { id ->
        liveData {
            val user = userRepository.getUser(id)
            emit(user)
        }
    }

    // Map user to display name
    val displayName: LiveData<String> = Transformations.map(user) { user ->
        user?.let { "${it.firstName} ${it.lastName}" } ?: "Unknown"
    }

    // Combine multiple LiveData sources
    private val _posts = MutableLiveData<List<Post>>()
    private val _comments = MutableLiveData<List<Comment>>()

    val feedItems: LiveData<FeedData> = MediatorLiveData<FeedData>().apply {
        var posts: List<Post>? = null
        var comments: List<Comment>? = null

        fun update() {
            if (posts != null && comments != null) {
                value = FeedData(posts!!, comments!!)
            }
        }

        addSource(_posts) { newPosts ->
            posts = newPosts
            update()
        }

        addSource(_comments) { newComments ->
            comments = newComments
            update()
        }
    }

    // Conditional transformation
    private val _searchQuery = MutableLiveData<String>()

    val searchResults: LiveData<List<Post>> = _searchQuery.switchMap { query ->
        if (query.isNullOrBlank()) {
            liveData { emit(emptyList<Post>()) }
        } else {
            liveData {
                val results = userRepository.searchPosts(query)
                emit(results)
            }
        }
    }

    // Custom transformation with distinct
    val postCount: LiveData<Int> = Transformations.distinctUntilChanged(
        Transformations.map(_posts) { it?.size ?: 0 }
    )

    fun setUserId(id: Int) {
        _userId.value = id
    }

    fun search(query: String) {
        _searchQuery.value = query
    }
}

data class FeedData(
    val posts: List<Post>,
    val comments: List<Comment>
)
1 file · kotlin Explain with highlit

LiveData transformations create derived data streams reactively. Transformations.map() converts values—like mapping User to username string. Transformations.switchMap() switches LiveData sources based on input, enabling dynamic queries. MediatorLiveData combines multiple LiveData sources, useful for aggregating data. The Mediator observes sources and updates when any changes. Transformations execute lazily only when observed. They maintain lifecycle awareness, preventing memory leaks. distinctUntilChanged() prevents duplicate emissions. These patterns eliminate manual observation management and enable declarative data flows. Transformations work with ViewModels to expose clean, transformed state to UI layers while keeping business logic separate.


Related snips

kotlin
package com.example.myapp

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp

Dependency injection with Hilt

kotlin android hilt
by Alex Chen 3 tabs
kotlin
package com.example.myapp.utils

import android.os.Build
import android.os.StrictMode
import android.os.Trace
import timber.log.Timber

Performance optimization and profiling

kotlin android performance
by Alex Chen 2 tabs
kotlin
package com.example.myapp.widget

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context

App widgets for home screen

kotlin android widget
by Alex Chen 2 tabs
kotlin
package com.example.myapp.data.repository

import com.example.myapp.data.local.PostDao
import com.example.myapp.data.local.PostEntity
import com.example.myapp.data.remote.ApiService
import com.example.myapp.models.Post

Unit testing with JUnit and MockK

kotlin android testing
by Alex Chen 2 tabs
kotlin
package com.example.myapp.utils

import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.app.PendingIntent

Notification channels and categories

kotlin android notifications
by Alex Chen 1 tab
kotlin
package com.example.myapp.data.remote

import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor

Retrofit for REST API networking

kotlin android retrofit
by Alex Chen 2 tabs

Share this code

Here's the card — post it anywhere.

LiveData transformations and mediators — share card
Link copied