Back to blog
September 18, 2025
3 min read

Build Your First Android App in Kotlin

Learn how to create your first Android application using Kotlin, from layout to main activity

Build Your First Android App in Kotlin

Let’s create a simple Android app using Kotlin. We’ll build a basic counter application that demonstrates fundamental Android concepts.

Project Setup

Create New Project

// build.gradle.kts (app level)
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.myfirstapp"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myfirstapp"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.11.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
}

Layout Design

Main Layout

<!-- res/layout/activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/counterText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="48sp"
        app:layout_constraintBottom_toTopOf="@+id/incrementButton"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/incrementButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Increment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Main Activity

Basic Activity

// MainActivity.kt
class MainActivity : AppCompatActivity() {
    private var counter = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val counterText = findViewById<TextView>(R.id.counterText)
        val incrementButton = findViewById<Button>(R.id.incrementButton)

        incrementButton.setOnClickListener {
            counter++
            counterText.text = counter.toString()
        }
    }
}

Adding Features

Save State

class MainActivity : AppCompatActivity() {
    private var counter = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Restore state
        counter = savedInstanceState?.getInt("counter", 0) ?: 0

        val counterText = findViewById<TextView>(R.id.counterText)
        val incrementButton = findViewById<Button>(R.id.incrementButton)

        // Update UI
        counterText.text = counter.toString()

        incrementButton.setOnClickListener {
            counter++
            counterText.text = counter.toString()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("counter", counter)
    }
}

Adding Animations

Button Animation

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val incrementButton = findViewById<Button>(R.id.incrementButton)

        incrementButton.setOnClickListener {
            // Scale animation
            incrementButton.animate()
                .scaleX(0.8f)
                .scaleY(0.8f)
                .setDuration(100)
                .withEndAction {
                    incrementButton.animate()
                        .scaleX(1f)
                        .scaleY(1f)
                        .setDuration(100)
                }
                .start()

            // Update counter
            counter++
            counterText.text = counter.toString()
        }
    }
}

Adding Styles

Custom Theme

<!-- res/values/themes.xml -->
<resources>
    <style name="Theme.MyFirstApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
    </style>
</resources>

Best Practices

View Binding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.incrementButton.setOnClickListener {
            counter++
            binding.counterText.text = counter.toString()
        }
    }
}

Constants

companion object {
    private const val COUNTER_KEY = "counter"
    private const val ANIMATION_DURATION = 100L
}

Error Handling

Basic Error Handling

class MainActivity : AppCompatActivity() {
    private var counter = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        try {
            counter = savedInstanceState?.getInt(COUNTER_KEY, 0) ?: 0
            updateCounterDisplay()
        } catch (e: Exception) {
            Log.e("MainActivity", "Error restoring state", e)
            counter = 0
            updateCounterDisplay()
        }
    }

    private fun updateCounterDisplay() {
        findViewById<TextView>(R.id.counterText).text = counter.toString()
    }
}

Conclusion

Building your first Android app helps you:

  • Understand basic Android concepts
  • Learn Kotlin for Android
  • Master UI development
  • Handle user interactions

Remember:

  • Follow Android best practices
  • Use proper error handling
  • Implement state management
  • Add user feedback

Stay tuned for our next post about MVVM Architecture in Kotlin!