Step 1: Kotlin Basics for Android — Variables, Functions and Classes

📚 Learn Android with Kotlin — Series
1. Kotlin 2. Android Studio 3. Activities 4. Intents 5. Fragments 6. RecyclerView 7. ViewModel 8. Room 🔒 9. Retrofit 🔒 10. Material 🔒 11. Firebase 🔒 12. Testing 🔒 13. Publish 🔒

Before you build a single Android screen, you need to speak the language. Kotlin is that language — and the good news is it's one of the most readable programming languages out there. If you've never written a line of code before, you can follow this. If you've coded in Java before, you'll love how much less you have to write.

This step covers the core concepts that show up in every Android app you'll ever build: variables, control flow, functions, lambdas, classes, and a few Kotlin-specific features that make the language genuinely enjoyable to work with.

Kotlin programming basics for Android development

Step 1 of the Learn Android with Kotlin series — starting with the language itself

1. Variables and Data Types

A variable is a named container for a value. In Kotlin there are exactly two ways to declare one — and picking the right one matters:

// var — mutable, value can change
var name: String = "Android Dev"
name = "Kotlin Learner"  // fine

// val — immutable, value cannot change after assignment
val language: String = "Kotlin"
// language = "Java"  // compile error
💡 Rule of thumb: Always start with val. Switch to var only when you know the value needs to change. Immutable code is safer, easier to reason about, and what Kotlin encourages.

Type Inference — Kotlin Knows the Type

You don't have to write the type explicitly — Kotlin infers it from the value:

val score = 100           // Kotlin infers: Int
val pi = 3.14159          // Kotlin infers: Double
val appName = "My App"    // Kotlin infers: String
val isActive = true       // Kotlin infers: Boolean

// Explicit types when needed
val price: Float = 9.99f
val bigNumber: Long = 9_999_999_999L

Common Data Types

Type Example Use for
Int 42 Whole numbers
Double 3.14 Decimal numbers
String "Hello" Text
Boolean true / false Yes/no values
Char 'K' Single character
Long 9_999_999_999L Very large numbers

String Templates — Build Strings the Kotlin Way

Instead of concatenating strings with +, Kotlin lets you embed variables directly inside a string using $:

val name = "Pragnesh"
val score = 98

// Old Java way — don't do this
println("Hello " + name + ", your score is " + score)

// Kotlin string template — clean and readable
println("Hello $name, your score is $score")

// For expressions, use ${}
println("Next score: ${score + 1}")
println("Name length: ${name.length} characters")

Null Safety — Kotlin's Superpower

In Java, NullPointerException is the most common crash. Kotlin eliminates it at compile time. By default, no variable can be null — you have to explicitly opt in:

// Non-nullable — cannot be null, ever
val username: String = "android_dev"
// username = null  // compile error

// Nullable — must add ? to allow null
var nickname: String? = null
nickname = "dev_123"  // fine
nickname = null       // also fine

// Safe call — only accesses if not null
println(nickname?.length)  // prints null if nickname is null, no crash

// Elvis operator — provide a default if null
val displayName = nickname ?: "Anonymous"

// Not-null assertion — use only when you're certain it's not null
val length = nickname!!.length  // throws if null — use sparingly

2. Control Flow

if-else — as an Expression

In Kotlin, if is not just a statement — it's an expression that returns a value. This means you can use it directly in assignments:

val age = 20

// Traditional use
if (age >= 18) {
    println("Adult")
} else {
    println("Minor")
}

// As an expression — assign result directly
val status = if (age >= 18) "Adult" else "Minor"
println(status)  // Adult

// Multiline expression
val message = if (age >= 18) {
    "Welcome! You can proceed."
} else {
    "Sorry, you must be 18 or older."
}

when — Kotlin's Smarter Switch

when replaces Java's switch and is far more powerful. It can match values, ranges, types, and also works as an expression:

val day = "Monday"

// Basic matching
when (day) {
    "Monday" -> println("Start of the work week")
    "Friday" -> println("Almost weekend!")
    "Saturday", "Sunday" -> println("It's the weekend!")
    else -> println("Just another weekday")
}

// As an expression with ranges
val score = 85
val grade = when (score) {
    in 90..100 -> "A"
    in 80..89  -> "B"
    in 70..79  -> "C"
    in 60..69  -> "D"
    else       -> "F"
}
println("Grade: $grade")  // Grade: B

Loops

// for loop with range
for (i in 1..5) {
    println("Count: $i")
}

// Loop with step
for (i in 0..10 step 2) {
    println(i)  // 0, 2, 4, 6, 8, 10
}

// Loop backwards
for (i in 5 downTo 1) {
    println(i)  // 5, 4, 3, 2, 1
}

// Loop over a list
val fruits = listOf("Apple", "Banana", "Cherry")
for (fruit in fruits) {
    println(fruit)
}

// while loop
var counter = 3
while (counter > 0) {
    println("Countdown: $counter")
    counter--
}

3. Functions and Lambdas

Functions

Functions group reusable code under a name. In Kotlin they're defined with the fun keyword:

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

// Single-expression function — cleaner for simple returns
fun greet(name: String) = "Hello, $name!"

// Function with default parameter
fun greet(name: String = "Android Dev") = "Hello, $name!"

// Usage
println(greet("Pragnesh"))   // Hello, Pragnesh!
println(greet())              // Hello, Android Dev!

// Function with multiple parameters
fun calculateTotal(price: Double, tax: Double = 0.18): Double {
    return price + (price * tax)
}

val total = calculateTotal(price = 100.0)  // named argument
println("Total: $total")  // Total: 118.0

Lambdas

A lambda is a function without a name — useful for passing behaviour as a parameter. You'll see them constantly in Android when setting click listeners, filtering lists, and working with coroutines:

// Lambda syntax: { parameters -> body }
val greet = { name: String -> "Hello, $name!" }
println(greet("World"))  // Hello, World!

// Lambda with single parameter — use 'it' as shorthand
val double = { it: Int -> it * 2 }
println(double(5))  // 10

// Lambdas with collections
val numbers = listOf(1, 2, 3, 4, 5, 6)

val evens = numbers.filter { it % 2 == 0 }
println(evens)  // [2, 4, 6]

val doubled = numbers.map { it * 2 }
println(doubled)  // [2, 4, 6, 8, 10, 12]

val sum = numbers.reduce { acc, num -> acc + num }
println(sum)  // 21

// Chaining — filter then map
val result = numbers
    .filter { it % 2 == 0 }
    .map { it * 10 }
println(result)  // [20, 40, 60]

4. Classes and Objects

Creating a Class

// Class with constructor parameters
class User(val name: String, val email: String) {

    // Property with custom getter
    val displayName: String
        get() = name.trim().ifBlank { "Unknown User" }

    // Method
    fun printInfo() {
        println("User: $name | Email: $email")
    }
}

// Create an object (instance)
val user = User("Pragnesh Ghoda", "pragnesh@example.com")
user.printInfo()
println(user.displayName)

Data Classes — The Android Developer's Best Friend

A data class automatically generates equals(), hashCode(), toString(), and copy(). You'll use data classes constantly in Android to represent API responses, database entities, and UI state:

// Regular class — you'd have to write equals/hashCode manually
// Data class — everything generated automatically
data class Article(
    val id: Int,
    val title: String,
    val author: String,
    val isBookmarked: Boolean = false
)

val article = Article(1, "Kotlin Basics", "Pragnesh")
println(article)
// Article(id=1, title=Kotlin Basics, author=Pragnesh, isBookmarked=false)

// copy() — create a modified version without changing the original
val bookmarked = article.copy(isBookmarked = true)
println(bookmarked)
// Article(id=1, title=Kotlin Basics, author=Pragnesh, isBookmarked=true)

// equals() works as expected
val same = Article(1, "Kotlin Basics", "Pragnesh")
println(article == same)  // true

Object — Singleton in One Keyword

Use object when you need exactly one instance of a class across your entire app — common for utilities, constants, and app-wide config:

object AppConfig {
    const val APP_NAME = "Android Academics"
    const val VERSION = "1.0.0"
    var isDebug = true

    fun printInfo() {
        println("$APP_NAME v$VERSION | Debug: $isDebug")
    }
}

// Access without creating an instance
AppConfig.printInfo()
println(AppConfig.APP_NAME)

Companion Object — Static Members in Kotlin

class NetworkManager private constructor() {

    companion object {
        // Factory method — common Android pattern
        fun create(): NetworkManager = NetworkManager()

        const val BASE_URL = "https://api.example.com"
    }
}

// Access companion members on the class, not an instance
val manager = NetworkManager.create()
println(NetworkManager.BASE_URL)

5. Bonus — Kotlin Features You'll Use in Android Immediately

Extension Functions

Add functions to existing classes without modifying them. Used everywhere in Android KTX libraries:

// Add a function to String
fun String.isValidEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Add a function to Int
fun Int.toDp(context: Context): Float {
    return this * context.resources.displayMetrics.density
}

// Usage — reads like it's built into the class
val email = "user@example.com"
println(email.isValidEmail())  // true
println("invalid".isValidEmail())  // false

Sealed Classes — Type-Safe State

You'll use sealed classes for UI state — Loading, Success, Error — as we cover in the ViewModel State Management post:

sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

// when with sealed class is exhaustive — no else needed
fun handleResult(result: Result<String>) {
    when (result) {
        is Result.Success -> println("Data: ${result.data}")
        is Result.Error   -> println("Error: ${result.message}")
        is Result.Loading -> println("Loading...")
    }
}
👉 What's next?
Now that you know the language, it's time to set up your workspace. In Step 2: Android Studio Setup — Install, Configure and Run Your First App we install the IDE, configure the emulator, and create your very first Android project.

Frequently Asked Questions

What is the difference between var and val in Kotlin?
var is mutable — its value can change. val is immutable — once assigned it cannot change. Always start with val and switch to var only when necessary.

What is a data class in Kotlin?
A data class automatically generates equals(), hashCode(), toString(), and copy() based on its constructor parameters. You'll use data classes constantly in Android for API responses, Room entities, and UI state models.

What is null safety in Kotlin?
Kotlin's type system distinguishes nullable (String?) from non-nullable (String) types at compile time — eliminating NullPointerException crashes. Use ?. for safe calls and ?: (Elvis operator) to provide fallback values.

What is a lambda in Kotlin?
A lambda is an anonymous function stored in a variable or passed as a parameter. Syntax: { parameters -> body }. Used constantly with collections (filter, map) and in Android for click listeners and coroutine callbacks.

📝 Step 1 Summary
  • val vs var — prefer val, use var only when the value must change
  • Type inference — Kotlin knows the type from the value, explicit types optional
  • String templates — use $variable and ${expression} in strings
  • Null safetyString? allows null, String never does
  • when — replaces switch, works with ranges, returns values
  • Data classes — automatic equals, hashCode, copy — use for models
  • Lambdas — anonymous functions, used with filter/map and click listeners
  • Sealed classes — type-safe state representation for UI
  • Extension functions — add methods to existing classes without inheritance

Pragnesh Ghoda

A forward-thinking developer offering more than 8 years of experience building, integrating, and supporting android applications for mobile and tablet devices on the Android platform. Talks about #kotlin and #android

Post a Comment

Please let us know about any concerns or query.

Previous Post Next Post

Contact Form