Kotlin Android Development

Build Android apps with Kotlin — Activities, Intents, layouts, and View Binding in Android Studio

Android Studio Activity Intent View Binding

Table of Contents

1Kotlin in Android Studio

Android Studio is the official IDE for Android development. It is built on IntelliJ IDEA and ships with first-class Kotlin support — syntax highlighting, refactoring, lint checks, and templates for Activities, Fragments, and Compose.

Create a Kotlin Android project

  1. Open Android Studio → New Project
  2. Choose a template (e.g. Empty Views Activity or Empty Compose Activity)
  3. Set Language to Kotlin
  4. Select minimum SDK (e.g. API 24+) and click Finish

Project structure (Kotlin app)

Typical module layoutapp/ ├── src/main/ │ ├── java/com/example/myapp/ # Kotlin source (.kt files) │ │ ├── MainActivity.kt │ │ └── ui/ │ ├── res/ │ │ ├── layout/ # XML layouts │ │ ├── values/ # strings, colors, themes │ │ └── drawable/ │ └── AndroidManifest.xml ├── build.gradle.kts # Kotlin DSL build script └── proguard-rules.pro

Enable Kotlin features in build.gradle.kts

app/build.gradle.ktsplugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { namespace = "com.example.myapp" compileSdk = 34 defaultConfig { applicationId = "com.example.myapp" minSdk = 24 targetSdk = 34 } buildFeatures { viewBinding = true } }
FeatureKotlin benefit in Android Studio
Convert Java to KotlinCode → Convert Java File to Kotlin File
Live templatestoast, logd, const shortcuts
LintKotlin null-safety and Android best-practice warnings
Gradle KTSBuild scripts in Kotlin — type-safe configuration
Getting started

If Android Studio is not installed yet, follow Kotlin Setup and the Android Installation Guide.

2Activities

An Activity represents a single screen with a user interface. In Kotlin, Activities subclass AppCompatActivity and override lifecycle methods to respond to user interaction and system events.

MainActivity.kt with View Bindingpackage com.example.myapp import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.example.myapp.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.btnHello.setOnClickListener { binding.tvGreeting.text = "Hello from Kotlin!" } } }

Activity lifecycle

CallbackWhen called
onCreate()Activity created — set up UI
onStart()Activity becoming visible
onResume()Activity in foreground, user interacting
onPause()Partially obscured — save lightweight state
onStop()No longer visible
onDestroy()Activity destroyed — release resources
Register Activity in AndroidManifest.xml<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Modern Android: For new apps, Google recommends single-Activity architecture with Fragments or Jetpack Compose — see Jetpack Compose and Activities & Fragments.

3Intents

An Intent is a messaging object used to request an action — start another Activity, open a URL, share content, or launch a system service. Kotlin makes Intent construction concise with named parameters and extension helpers.

Explicit Intent — start another Activity

Explicit Intent// From MainActivity — open DetailActivity val intent = Intent(this, DetailActivity::class.java) intent.putExtra("USER_ID", 101) intent.putExtra("USER_NAME", "Nikhil") startActivity(intent) // Kotlin apply style — cleaner val intent = Intent(this, DetailActivity::class.java).apply { putExtra("USER_ID", 101) putExtra("USER_NAME", "Nikhil") } startActivity(intent)

Receive data in target Activity

DetailActivity.ktclass DetailActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val userId = intent.getIntExtra("USER_ID", -1) val userName = intent.getStringExtra("USER_NAME") ?: "Unknown" println("User: $userName (ID: $userId)") } }

Implicit Intent — system chooses app

Share text, open URL, dial phone// Share text val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, "Check out Nikhil Learn Hub!") } startActivity(Intent.createChooser(shareIntent, "Share via")) // Open browser val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://kotlinlang.org")) startActivity(browserIntent) // Dial phone number val dialIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:+911234567890")) startActivity(dialIntent)
Intent typePurposeExample
ExplicitStart known component in your appIntent(this, DetailActivity::class.java)
ImplicitSystem resolves matching appsIntent(ACTION_SEND)
putExtraPass primitive/String dataputExtra("KEY", value)
Activity Result APIGet result back from ActivityregisterForActivityResult
Type-safe navigation

For complex apps, use Jetpack Navigation Component instead of manual Intents — supports graphs, deep links, and safe args.

4Layouts

Layouts define UI structure in XML under res/layout/. Android inflates layout files into View objects at runtime. Kotlin Activities reference layouts via View Binding or setContentView.

activity_main.xml

res/layout/activity_main.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/tvGreeting" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Welcome" android:textSize="24sp" /> <Button android:id="@+id/btnHello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Say Hello" /> </LinearLayout>

Common layout containers

LayoutBehaviorUse case
LinearLayoutSingle row or columnSimple stacked UI
RelativeLayoutPosition relative to siblings/parentLegacy — prefer ConstraintLayout
ConstraintLayoutFlexible constraints, flat hierarchyRecommended for complex screens
FrameLayoutStack views on top of each otherFragments container, overlays
RecyclerViewScrollable list of itemsFeeds, lists — see Android tutorial

ConstraintLayout example

ConstraintLayout snippet<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Kotlin Android" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Resources: Extract strings to res/values/strings.xml and colors to colors.xml — reference with @string/app_name for localization and theming. More in Layouts & Widgets.

5View Binding

View Binding generates a binding class for each XML layout (e.g. ActivityMainBinding for activity_main.xml). It replaces findViewById with type-safe, null-safe references — the recommended way to access views in Kotlin Android projects.

Enable View Binding

build.gradle.ktsandroid { buildFeatures { viewBinding = true } }

Use in Activity

Activity with View Bindingclass MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.tvGreeting.text = getString(R.string.welcome_message) binding.btnHello.setOnClickListener { binding.tvGreeting.text = "Hello, Kotlin!" } } override fun onDestroy() { super.onDestroy() // binding is cleared when Activity is destroyed } }

View Binding in Fragment

Fragment patternclass HomeFragment : Fragment() { 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 onViewCreated(view: View, savedInstanceState: Bundle?) { binding.tvWelcome.text = "Welcome Home" } override fun onDestroyView() { super.onDestroyView() _binding = null // prevent memory leaks } }
ApproachType safe?Status
findViewByIdNo (casts required)Legacy — avoid
View BindingYesRecommended
Data BindingYes + binding expressionsWhen binding UI to ViewModel in XML
Kotlin syntheticsPartialDeprecated — removed
Naming rule

Layout file activity_main.xml → binding class ActivityMainBinding. Underscores are removed and words are PascalCase.

6Kotlin Android Extensions

Kotlin Android Extensions (also called Kotlin synthetics) allowed direct access to views by ID without findViewById — e.g. textView.text = "Hello" after importing kotlinx.android.synthetic. This plugin is deprecated and removed; migrate to View Binding.

Old synthetics approach (deprecated)

Deprecated — do not use// REMOVED — shown for reference only // import kotlinx.android.synthetic.main.activity_main.* // class MainActivity : AppCompatActivity() { // override fun onCreate(savedInstanceState: Bundle?) { // super.onCreate(savedInstanceState) // setContentView(R.layout.activity_main) // tvGreeting.text = "Hello" // direct view access // btnHello.setOnClickListener { ... } // } // }

Why synthetics were removed

IssueProblem
No null safetyCould crash if view missing from layout
Fragment leaksSynthetics could hold Activity view references after destroy
No compile-time bindingIDs not verified as strongly as View Binding
MaintenanceGoogle/JetBrains replaced with View Binding

Migration: synthetics → View Binding

Before and after// BEFORE (synthetics) // tvGreeting.text = "Hello" // AFTER (View Binding) binding.tvGreeting.text = "Hello"

Other useful Kotlin Android extensions

While layout synthetics are gone, Kotlin extension functions on Android types remain very useful:

Kotlin extension examples// KTX extensions (androidx.core) import androidx.core.view.isVisible fun updateUI(binding: ActivityMainBinding, loading: Boolean) { binding.progressBar.isVisible = loading binding.tvGreeting.isVisible = !loading } // Custom extension fun Context.showToast(message: String) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show() } // Usage in Activity showToast("Saved successfully")
Use View Binding

For all new XML-based screens — type-safe view access.

Use KTX

core-ktx, activity-ktx, fragment-ktx for concise APIs.

Custom extensions

Add helpers like showToast(), hideKeyboard().

Avoid synthetics

Remove kotlin-android-extensions plugin from Gradle if present.

Remove deprecated plugin: Delete kotlin("android.extensions") or id("kotlin-android-extensions") from build.gradle and enable View Binding instead. Details in ViewBinding & DataBinding.

7Summary Cheatsheet

TopicKey Takeaway
Kotlin in Android StudioNew project → Language: Kotlin; enable View Binding in Gradle
ActivitiesAppCompatActivity; onCreate → inflate layout → set listeners
IntentsExplicit (in-app); Implicit (system); putExtra for data
LayoutsXML in res/layout/; ConstraintLayout for complex UI
View BindingActivityMainBinding.inflate() — recommended, type-safe
Kotlin Android ExtensionsSynthetics deprecated — migrate to View Binding + KTX
Next lessonJetpack Compose — declarative UI in Kotlin