UI Widgets

Essential Android views for text, input, selection, and feedback

TextView EditText Button SeekBar

Table of Contents

Widgets Overview

Widgets (Views) are the building blocks of every Android screen. You declare them in XML layouts and reference them in Kotlin with findViewById or View Binding.

View vs ViewGroup: A View displays content (TextView, Button). A ViewGroup is a layout that holds other views (LinearLayout, ConstraintLayout).

WidgetPurposeUser Interaction
TextViewDisplay read-only textNone (can be clickable)
EditTextText input fieldKeyboard typing
ButtonTrigger actionsTap
ImageViewDisplay images/iconsTap (optional)
CheckBoxMultiple selectionsToggle on/off
RadioButtonSingle selection in a groupPick one option
SwitchOn/off settingToggle
SpinnerDropdown selectionPick from list
ProgressBarLoading indicatorNone
SeekBarSlide to pick a valueDrag slider

1TextView

TextView displays static or dynamic text — titles, labels, descriptions, and formatted content.

XML example

XML — TextView attributes<TextView android:id="@+id/tvWelcome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/welcome_message" android:textSize="20sp" android:textStyle="bold" android:textColor="@color/primary_dark" android:lineSpacingExtra="4dp" android:maxLines="2" android:ellipsize="end" android:drawableStart="@drawable/ic_star" android:drawablePadding="8dp" android:gravity="center_vertical" />

Kotlin — update text programmatically

Kotlin — MainActivity.ktval tvWelcome = findViewById<TextView>(R.id.tvWelcome) tvWelcome.text = "Hello, Nikhil!" tvWelcome.setTextColor(ContextCompat.getColor(this, R.color.primary)) // HTML formatted text tvWelcome.text = HtmlCompat.fromHtml( "<b>Bold</b> and <i>italic</i>", HtmlCompat.FROM_HTML_MODE_LEGACY )

Common TextView attributes

AttributeDescription
android:textString resource or literal text
android:textSizeSize in sp (scales with accessibility)
android:textStylebold, italic, or bold|italic
android:maxLines + ellipsizeTruncate long text with "..."
android:autoLinkAuto-detect phone, email, web links

2EditText

EditText is a subclass of TextView optimized for user text input. Use inputType to control the keyboard and validation behavior.

Login form fields

XML — EditText examples<EditText android:id="@+id/etEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/email_hint" android:inputType="textEmailAddress" android:autofillHints="emailAddress" android:maxLines="1" android:imeOptions="actionNext" /> <EditText android:id="@+id/etPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/password_hint" android:inputType="textPassword" android:maxLines="1" android:imeOptions="actionDone" /> <EditText android:id="@+id/etBio" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/bio_hint" android:inputType="textMultiLine|textCapSentences" android:minLines="3" android:gravity="top" />

Kotlin — read input and validate

Kotlin — Get and validate inputval email = findViewById<EditText>(R.id.etEmail).text.toString().trim() val password = findViewById<EditText>(R.id.etPassword).text.toString() if (email.isEmpty()) { findViewById<EditText>(R.id.etEmail).error = "Email is required" return } if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) { findViewById<EditText>(R.id.etEmail).error = "Invalid email format" return }

Common inputType values

inputTypeUse Case
textGeneral text
textEmailAddressEmail with @ keyboard
textPasswordHidden password input
number / numberDecimalNumeric input
phonePhone number dial pad
textMultiLineParagraph / message box

3Button

Button triggers actions when tapped. Material Design provides styled variants: MaterialButton, outlined, and text buttons.

XML — standard and Material buttons

XML — Button variants<Button android:id="@+id/btnSubmit" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/submit" android:enabled="true" android:drawableStart="@drawable/ic_send" android:drawablePadding="8dp" /> <com.google.android.material.button.MaterialButton android:id="@+id/btnOutlined" style="@style/Widget.Material3.Button.OutlinedButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/cancel" /> <com.google.android.material.button.MaterialButton android:id="@+id/btnText" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/learn_more" />

Kotlin — click listener

Kotlin — Button click handlingfindViewById<Button>(R.id.btnSubmit).setOnClickListener { Toast.makeText(this, "Submitted!", Toast.LENGTH_SHORT).show() } // Disable button during loading val btn = findViewById<Button>(R.id.btnSubmit) btn.isEnabled = false btn.text = "Loading..." // Re-enable after async work completes btn.isEnabled = true btn.text = getString(R.string.submit)

Tip: Use android:minHeight="48dp" for touch-friendly tap targets. Material buttons handle this by default.

4ImageView

ImageView displays drawable resources, bitmaps, or icons. Always set contentDescription for accessibility (TalkBack).

XML example

XML — ImageView<ImageView android:id="@+id/ivProfile" android:layout_width="120dp" android:layout_height="120dp" android:src="@drawable/ic_avatar_placeholder" android:scaleType="centerCrop" android:background="@drawable/circle_bg" android:contentDescription="@string/profile_photo" android:padding="4dp" /> <ImageView android:id="@+id/ivBanner" android:layout_width="match_parent" android:layout_height="180dp" android:src="@drawable/banner" android:scaleType="fitCenter" android:adjustViewBounds="true" android:contentDescription="@string/app_banner" />

Kotlin — load image with Coil

Kotlin — Load URL with Coil library// dependencies { implementation("io.coil-kt:coil:2.6.0") } val ivProfile = findViewById<ImageView>(R.id.ivProfile) ivProfile.load("https://example.com/avatar.jpg") { placeholder(R.drawable.ic_avatar_placeholder) error(R.drawable.ic_error) crossfade(true) transformations(CircleCropTransformation()) }

scaleType options

scaleTypeBehavior
centerCropFill view, crop edges (profile photos)
fitCenterFit entire image inside view
centerInsideScale down if larger than view
fitXYStretch to fill (may distort)

5CheckBox

CheckBox allows users to select zero or more options independently. Each checkbox toggles on its own.

XML — terms and interests

XML — CheckBox group<CheckBox android:id="@+id/cbTerms" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/agree_terms" android:checked="false" /> <CheckBox android:id="@+id/cbKotlin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Kotlin" /> <CheckBox android:id="@+id/cbJava" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Java" /> <CheckBox android:id="@+id/cbCompose" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Jetpack Compose" />

Kotlin — listen for changes

Kotlin — CheckBox listenersfindViewById<CheckBox>(R.id.cbTerms).setOnCheckedChangeListener { _, isChecked -> findViewById<Button>(R.id.btnSubmit).isEnabled = isChecked } val interests = mutableListOf<String>() findViewById<CheckBox>(R.id.cbKotlin).setOnCheckedChangeListener { _, checked -> if (checked) interests.add("Kotlin") else interests.remove("Kotlin") }

6RadioButton

RadioButton lets users pick exactly one option from a set. Group them inside a RadioGroup so selecting one deselects the others.

XML — payment method selection

XML — RadioGroup with RadioButtons<RadioGroup android:id="@+id/rgPayment" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/rbCreditCard" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/credit_card" android:checked="true" /> <RadioButton android:id="@+id/rbUpi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/upi" /> <RadioButton android:id="@+id/rbCod" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/cash_on_delivery" /> </RadioGroup>

Kotlin — get selected option

Kotlin — RadioGroup listenerfindViewById<RadioGroup>(R.id.rgPayment) .setOnCheckedChangeListener { group, checkedId -> val selected = when (checkedId) { R.id.rbCreditCard -> "Credit Card" R.id.rbUpi -> "UPI" R.id.rbCod -> "Cash on Delivery" else -> "Unknown" } Toast.makeText(this, "Selected: $selected", Toast.LENGTH_SHORT).show() }

7Switch

Switch (Material SwitchMaterial) is a toggle for binary on/off settings — notifications, dark mode, Wi-Fi, etc.

XML example

XML — Switch / SwitchMaterial<Switch android:id="@+id/switchNotifications" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/enable_notifications" android:checked="true" android:showText="false" /> <com.google.android.material.switchmaterial.SwitchMaterial android:id="@+id/switchDarkMode" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/dark_mode" android:checked="false" />

Kotlin — toggle listener

Kotlin — Switch handlingfindViewById<Switch>(R.id.switchNotifications) .setOnCheckedChangeListener { _, isChecked -> if (isChecked) { enablePushNotifications() } else { disablePushNotifications() } } // Read current state val darkModeEnabled = findViewById<Switch>(R.id.switchDarkMode).isChecked

8Spinner

Spinner shows a dropdown list for selecting one item — country, language, category, etc. Populate it with an ArrayAdapter.

XML layout

XML — Spinner<Spinner android:id="@+id/spinnerCountry" android:layout_width="match_parent" android:layout_height="wrap_content" android:spinnerMode="dropdown" android:prompt="@string/select_country" android:minHeight="48dp" />

String array resource

XML — res/values/arrays.xml<resources> <string-array name="countries"> <item>India</item> <item>United States</item> <item>United Kingdom</item> <item>Canada</item> <item>Australia</item> </string-array> </resources>

Kotlin — setup adapter and listener

Kotlin — Spinner with ArrayAdapterval spinner = findViewById<Spinner>(R.id.spinnerCountry) val countries = resources.getStringArray(R.array.countries) val adapter = ArrayAdapter( this, android.R.layout.simple_spinner_item, countries ).also { it.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } spinner.adapter = adapter spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { val selected = countries[position] Log.d("Spinner", "Selected country: $selected") } override fun onNothingSelected(parent: AdapterView<*>?) {} }

9ProgressBar

ProgressBar indicates loading or task progress. Use indeterminate mode for unknown duration, determinate mode when you know the percentage.

XML — indeterminate and horizontal

XML — ProgressBar variants<!-- Spinning loader (unknown duration) --> <ProgressBar android:id="@+id/progressLoading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="true" android:visibility="gone" /> <!-- Horizontal bar (known progress 0–100) --> <ProgressBar android:id="@+id/progressDownload" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="0" android:visibility="visible" />

Kotlin — show/hide and update progress

Kotlin — ProgressBar controlval progressLoading = findViewById<ProgressBar>(R.id.progressLoading) val progressDownload = findViewById<ProgressBar>(R.id.progressDownload) // Show indeterminate loader progressLoading.visibility = View.VISIBLE // Simulate download progress lifecycleScope.launch { for (i in 0..100 step 5) { progressDownload.progress = i delay(200) } progressLoading.visibility = View.GONE Toast.makeText(this@MainActivity, "Download complete!", Toast.LENGTH_SHORT).show() }

Material alternative: For modern apps, consider LinearProgressIndicator or CircularProgressIndicator from Material Components for consistent Material 3 styling.

10SeekBar

SeekBar is a draggable slider for choosing a value in a range — volume, brightness, font size, rating, etc.

XML example

XML — SeekBar with label<TextView android:id="@+id/tvVolumeLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/volume_50" /> <SeekBar android:id="@+id/seekVolume" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:stepSize="1" />

Kotlin — track progress changes

Kotlin — SeekBar listenerval seekBar = findViewById<SeekBar>(R.id.seekVolume) val tvLabel = findViewById<TextView>(R.id.tvVolumeLabel) seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { tvLabel.text = "Volume: $progress%" } override fun onStartTrackingTouch(seekBar: SeekBar?) {} override fun onStopTrackingTouch(seekBar: SeekBar?) { val finalValue = seekBar?.progress ?: 0 saveVolumePreference(finalValue) } })

SeekBar vs Slider (Material)

WidgetPackageNotes
SeekBarandroid.widgetClassic Android slider, widely used
SliderMaterial ComponentsMaterial 3 styling, value label, range support

11Hands-On Exercises

1

Build a profile screen with a TextView title, ImageView avatar, and two EditText fields (name, bio). Add a Button that shows a Toast with the entered name.

2

Add email validation to the EditText: show an inline error if the format is invalid using .error = "...".

3

Create a survey with three CheckBox options (hobbies) and a RadioGroup for experience level (Beginner / Intermediate / Advanced). Log selections on submit.

4

Add a Switch for "Receive newsletter" and disable the submit button unless terms CheckBox is checked.

5

Populate a Spinner with 5 cities using ArrayAdapter. Display the selected city in a TextView below.

6

Show an indeterminate ProgressBar for 3 seconds on button click, then hide it. Add a horizontal ProgressBar that fills from 0 to 100.

7

Add a SeekBar (0–100) that updates a "Font Size" label live. Save the value in SharedPreferences when the user releases the slider.

UI Widgets MCQ Practice

10 Basic MCQs 10 Advanced MCQs

10 Basic UI Widgets MCQs

1

TextView displays?

ARead-only text
BVideo stream only
CGPS coordinates only
DDex files
Explanation: TextView shows labels and static/copyable text.
2

EditText is for?

AUser text input
BImages only
CBackground services
DAPK signing
Explanation: EditText extends TextView with editable input and IME.
3

Button click listener interface?

AView.OnClickListener
BServiceConnection
CParcelable
DCursor
Explanation: setOnClickListener { } handles tap events.
4

ImageView loads drawable via?

Aandroid:src or setImageResource
BGradle sync
CManifest intent
Dadb install
Explanation: src attribute references @drawable or setImageBitmap in code.
5

CheckBox allows?

AMultiple selections independently
BSingle selection only
CNo user input
DNetwork calls
Explanation: Each CheckBox toggles independently.
6

RadioButton group ensures?

ASingle selection among group
BMultiple mandatory
CNo UI
DAuto GPS
Explanation: RadioGroup enforces one selected RadioButton.
7

Switch toggles?

ABoolean on/off state
BVideo playback only
CSQL transactions
DFragment back stack
Explanation: Switch (CompoundButton) for settings-style toggles.
8

Spinner shows?

ADropdown item selection
BInfinite list virtualized
CMap tiles
DLogcat
Explanation: Spinner uses adapter for dropdown selection (consider Material ExposedDropdownMenu).
9

ProgressBar indicates?

ALoading or indeterminate progress
BFinal score only
CBattery kernel
DLint results
Explanation: Horizontal or circular progress indicators.
10

SeekBar lets user?

ADrag to choose value in range
BType text
CSelect date only
DCompile code
Explanation: SeekBar is draggable progress for volume, brightness, etc.

10 Advanced UI Widgets MCQs

11

TextInputLayout provides?

AMaterial hint/error/helper for EditText
BDatabase layout
CNavigation graph
DHAL bridge
Explanation: TextInputLayout wraps TextInputEditText with floating labels.
12

inputType on EditText?

AControls keyboard and input validation style
BGradle plugin
CAPI 34 only
DIcon density
Explanation: textPassword, number, textEmailAddress, etc.
13

CompoundButton includes?

ACheckBox, RadioButton, Switch
BTextView only
CRecyclerView
DNavHost
Explanation: Shared toggle behavior and checked change listeners.
14

ImageView scaleType centerCrop?

AScales image filling view, may crop
BNever crops
COnly vector
DDisables GPU
Explanation: centerCrop maintains aspect ratio filling bounds.
15

RecyclerView vs Spinner adapter?

ARecyclerView recycles all item types; Spinner uses dropdown adapter
BIdentical
CSpinner faster always
DNeither uses adapter
Explanation: Different UX patterns — Spinner for compact selection.
16

Accessibility contentDescription on ImageView?

AScreen reader spoken label
BEncryption key
CLayout weight
DDex name
Explanation: Essential for TalkBack when image conveys meaning.
17

StateListDrawable?

ADifferent drawable per widget state (pressed, disabled)
BAnimation timeline
CSQL state
DProcess state
Explanation: selector XML in drawable for button states.
18

autofill hints on EditText?

AHelp password managers categorize fields
BDisable keyboard
CRemove focus
DStart Service
Explanation: autofillHints username/password improve Autofill Framework.
19

MaterialButton vs Button?

AMaterial theming, ripple, stroke styles
BNo difference
CMaterialButton deprecated
DOnly in Compose
Explanation: MaterialButton follows Material Design 3 attributes.
20

ToggleButton vs Switch?

ABoth toggle; Switch is Material settings pattern
BToggleButton is only legal option
CNeither toggles
DServices only
Explanation: Prefer Switch or MaterialSwitch for settings UIs.
Click an option to select, then check answers.

UI Widgets Interview Q&A

15 topic-focused questions for interviews and revision.

1Difference between TextView and EditText.easy
Answer: TextView displays text; EditText adds editing, cursor, input method integration, and inputType.
2How to handle Button click in Kotlin?easy
Answer: binding.btnSubmit.setOnClickListener { /* action */ } or setOnClickListener(object : View.OnClickListener { ... }).
3Load image from drawable in ImageView.easy
Answer: android:src="@drawable/logo" in XML or imageView.setImageResource(R.drawable.logo).
4RadioGroup vs separate CheckBoxes.easy
Answer: RadioGroup: mutually exclusive choice; CheckBoxes: independent multi-select.
5Spinner setup steps.medium
Answer: Create ArrayAdapter with items; spinner.adapter = adapter; onItemSelectedListener for selection.
6Show and hide ProgressBar during network call.medium
Answer: Visible during loading on main thread start; hide in coroutine completion on main thread.
7SeekBar get progress value.easy
Answer: seekBar.progress in OnSeekBarChangeListener onProgressChanged or onStopTrackingTouch.
8Validate EditText empty before submit.easy
Answer: Check text.isNullOrBlank(); show TextInputLayout.error for Material forms.
9Switch listener.easy
Answer: setOnCheckedChangeListener { _, isChecked -> } or switch.setOnClickListener reading isChecked.
10Why TextInputLayout over plain EditText?medium
Answer: Floating labels, error text, helper text, counter, and Material styling.
11inputType textPassword effect.easy
Answer: Masks characters and may suggest secure keyboard.
12ImageView with network URL?medium
Answer: Use Coil/Glide/Picasso — never block main thread; ImageView doesn't load HTTP by default.
13Enable/disable Button based on CheckBox.easy
Answer: checkbox.setOnCheckedChangeListener { _, checked -> button.isEnabled = checked }.
14Spinner vs RecyclerView for long lists.medium
Answer: RecyclerView virtualizes; Spinner loads all items — poor for huge datasets.
15Widget state saving on rotation.medium
Answer: Use ViewModel or onSaveInstanceState for user input; ViewBinding with ViewModel preferred.