Kotlin Android UI Basics
The Android UI is built from Views — visible elements on the screen like text, buttons, and images. You design the layout in XML and control it from Kotlin code. This topic covers the most essential views, layouts, and click handling.
XML Layout File
Every screen in an Android app has an XML layout file stored in res/layout/. This file describes what appears on screen and where.
<!-- res/layout/activity_main.xml -->
<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="Hello, World!"
android:textSize="20sp" />
<Button
android:id="@+id/btnClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tap Me"
android:layout_marginTop="16dp" />
</LinearLayout>
Common Dimension Units
Unit | Purpose -----|----------------------------------------------------------- dp | Density-independent pixels — use for margins, padding, sizes sp | Scale-independent pixels — use for text sizes only px | Actual screen pixels — avoid, looks different on every device
Common Views
View | Purpose ----------------|------------------------------------------- TextView | Display text (read-only label) EditText | User input text field Button | Tappable button ImageView | Display an image CheckBox | On/off toggle with a box RadioButton | Single choice from a group Switch | On/off toggle with a slide RecyclerView | Scrollable list of items (efficient) ProgressBar | Show loading progress
Connecting XML Views to Kotlin Code
Use findViewById to get a reference to a view by its ID.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tvGreeting = findViewById<TextView>(R.id.tvGreeting)
val btnClick = findViewById<Button>(R.id.btnClick)
btnClick.setOnClickListener {
tvGreeting.text = "Button tapped!"
}
}
}
ViewBinding — Safer and Cleaner (Recommended)
ViewBinding generates a binding class for each XML layout. You access views as properties — no casting, no null crashes.
// Enable in build.gradle.kts:
android {
buildFeatures { viewBinding = true }
}
// In Activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnClick.setOnClickListener {
binding.tvGreeting.text = "Hello from ViewBinding!"
}
}
}
Layout Types
LinearLayout — Stack Views in a Line
<LinearLayout
android:orientation="vertical"> <!-- or "horizontal" -->
<TextView ... />
<Button ... />
<EditText ... />
</LinearLayout>
Vertical: Horizontal:
[TextView ] [TextView][Button][EditText]
[Button ]
[EditText ]
ConstraintLayout — Position With Constraints
ConstraintLayout positions views relative to each other or to the parent. It creates flat, high-performance layouts.
<androidx.constraintlayout.widget.ConstraintLayout ...>
<Button
android:id="@+id/btnOk"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="32dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Handling User Input with EditText
// XML
<EditText
android:id="@+id/etName"
android:hint="Enter your name"
android:inputType="textPersonName" />
// Kotlin
binding.btnSubmit.setOnClickListener {
val name = binding.etName.text.toString().trim()
if (name.isEmpty()) {
binding.etName.error = "Name is required"
} else {
binding.tvGreeting.text = "Hello, $name!"
}
}
Toast — Quick Pop-Up Message
Toast.makeText(this, "Saved successfully!", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Long message here", Toast.LENGTH_LONG).show()
Navigating Between Activities
// Start a new Activity
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("username", "Priya")
startActivity(intent)
// In SecondActivity — receive the data
val username = intent.getStringExtra("username")
binding.tvUser.text = "Welcome, $username!"
Diagram — Intent Flow Between Activities
MainActivity
│
│ Intent(this, SecondActivity::class.java)
│ .putExtra("username", "Priya")
│
▼
Android System routes the Intent
│
▼
SecondActivity
onCreate()
intent.getStringExtra("username") → "Priya"
