Essential Kotlin Concepts for Android Development

Variables and Data Types

// Immutable (read-only) variables
val name = "John"                    // String
val age = 25                         // Int
val isStudent = true                 // Boolean
val height = 5.9                     // Double

// Mutable variables
var count = 0                        // Can be changed
var message: String? = null          // Nullable String

// Late initialization (common in Android)
private lateinit var binding: FragmentHomeBinding

Functions

// Simple function
fun greet(name: String): String {
    return "Hello, $name!"
}

// Single expression function
fun add(a: Int, b: Int) = a + b

// Function with default parameters
fun createUser(name: String, age: Int = 18) {
    // age defaults to 18 if not provided
}

// Extension function
fun String.isEmail(): Boolean {
    return this.contains("@")
}

Classes and Objects

// Data class (automatically generates equals, hashCode, toString)
data class Person(
    val name: String,
    val age: Int
)

// Regular class
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}

// Object (singleton)
object AppConfig {
    const val API_URL = "https://api.example.com"
}

Null Safety

// Nullable types
var name: String? = null

// Safe call operator
val length = name?.length  // Returns null if name is null

// Elvis operator (default value)
val length = name?.length ?: 0  // Returns 0 if name is null

// Not-null assertion (use carefully!)
val length = name!!.length  // Throws exception if name is null

// Safe cast
val number = value as? Int  // Returns null if cast fails

Collections

// Lists
val numbers = listOf(1, 2, 3, 4, 5)
val mutableNumbers = mutableListOf(1, 2, 3)

// Maps
val ages = mapOf("John" to 25, "Jane" to 30)
val mutableAges = mutableMapOf("John" to 25)

// Sets
val uniqueNumbers = setOf(1, 2, 3, 3, 4)  // Result: [1, 2, 3, 4]

Control Flow

// If expression
val max = if (a > b) a else b

// When expression (like switch)
when (day) {
    1 -> "Monday"
    2 -> "Tuesday"
    in 3..5 -> "Midweek"
    else -> "Weekend"
}

// For loops
for (i in 1..10) { }           // Range
for (item in list) { }         // Collection
for ((key, value) in map) { }  // Map entries

Lambda Expressions

// Lambda syntax
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }  // [2, 4, 6, 8, 10]
val evens = numbers.filter { it % 2 == 0 }  // [2, 4]

// Higher-order functions
fun processNumbers(numbers: List<Int>, processor: (Int) -> Int): List<Int> {
    return numbers.map(processor)
}

// Usage
val result = processNumbers(listOf(1, 2, 3)) { it * 2 }

Coroutines (Async Programming)

// Suspend function
suspend fun fetchData(): String {
    delay(1000)  // Non-blocking delay
    return "Data loaded"
}

// Launch coroutine
lifecycleScope.launch {
    val data = fetchData()
    updateUI(data)
}

// Flow (reactive streams)
fun getNumbers(): Flow<Int> = flow {
    repeat(5) {
        emit(it)
        delay(1000)
    }
}

// Collect from Flow
lifecycleScope.launch {
    getNumbers().collect { number ->
        println(number)
    }
}

Common Android Patterns

// ViewBinding
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    _binding = FragmentHomeBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

// StateFlow in ViewModel
class MyViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(UiState())
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    fun updateState(newState: UiState) {
        _uiState.value = newState
    }
}

// Observing StateFlow in Fragment
viewLifecycleOwner.lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            updateUI(state)
        }
    }
}

String Templates

val name = "John"
val age = 25

// String interpolation
val message = "Hello, $name! You are $age years old."
val calculation = "The result is ${a + b}"

// Multi-line strings
val html = """
    <html>
        <body>
            <h1>Hello, $name!</h1>
        </body>
    </html>
""".trimIndent()

Scope Functions

val person = Person("John", 25)

// let - execute block and return result
val result = person.let { it.age * 2 }

// apply - execute block and return object
person.apply {
    age = 26
    name = "Johnny"
}

// with - execute block with object as receiver
with(person) {
    println("Name: $name, Age: $age")
}

// run - execute block and return result
val fullInfo = person.run {
    "$name is $age years old"
}

Exception Handling

// Try-catch
try {
    val result = riskyOperation()
} catch (e: Exception) {
    println("Error: ${e.message}")
} finally {
    println("Cleanup")
}

// Try as expression
val result = try {
    riskyOperation()
} catch (e: Exception) {
    defaultValue
}

This quick reference covers the most important Kotlin concepts you'll encounter in Android development. Practice these patterns and you'll be well on your way to becoming proficient in Kotlin!