Mobile ProgrammingUnit 512 min read
Dialogs, Menus & User Inputs: Custom UI Interactions in Android
Unit 5 of Mobile Programming: This note explains how to create interactive user interfaces in Android using dialogs (alert, custom, progress), menus (options, context, popup), and input methods (edit text, buttons, spinners) with practical examples and code traces.
TAKEAWAYS:
- Learn to design alert dialogs (confirmation, input prompts) and custom dialogs (sliders, multi-step forms) with XML layouts and Java logic.
- Implement options menus (top toolbar) and context menus (long-click) to trigger actions like color changes or data deletion.
- Use popup menus for quick action lists (e.g., text editing tools) and toasts for short feedback messages.
- Understand view binding (findViewById vs. Kotlin’s
viewBinding) and input validation (regex, error handling). - Compare dialog types by use case (e.g., progress dialogs for async tasks vs. alert dialogs for critical actions).
- Apply these techniques to real apps like eSewa’s transaction confirmations (alert dialogs) or Pathao’s route selection (popup menus).
1. Dialogs in Android: Types and Implementation
Dialogs are temporary windows that pause the main app flow to request user input or confirmation. They are essential for forms, settings, and feedback.
1.1 Alert Dialogs
Alert dialogs display a message with optional buttons (OK, Cancel, Yes/No). Use cases:
- Confirming actions (e.g., "Delete this item?").
- Showing errors (e.g., "Invalid email format").
- Prompting for input (e.g., "Enter your password").
Example: Simple Alert Dialog
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Warning");
alertDialogBuilder.setMessage("Are you sure you want to exit?");
alertDialogBuilder.setPositiveButton("Yes", (dialog, which) -> {
finish(); // Close app
});
alertDialogBuilder.setNegativeButton("No", (dialog, which) -> dialog.dismiss());
alertDialogBuilder.show();
Visual: Alert Dialog Flow
flowchart TD
A["User clicks 'Exit'"] --> B{"Alert Dialog"}
B -->|"Yes"| C["Close App"]
B -->|"No"| D["Dismiss Dialog"]Trace Table: Dialog State Changes
| Step | Action | Dialog State |
|---|---|---|
| 1 | setTitle("Warning") |
Title: "Warning", Message: null |
| 2 | setMessage("Are you sure?") |
Title: "Warning", Message: "..." |
| 3 | setPositiveButton("Yes") |
Buttons: ["Yes", "No"] |
| 4 | User taps "Yes" | App closes (finish()) |
1.2 Custom Dialogs
For complex inputs (e.g., sliders, multi-field forms), use custom dialogs with XML layouts.
Example: Custom Dialog for Simple Interest Calculation
XML Layout (custom_dialog.xml):
<LinearLayout xmlns:android="..." android:orientation="vertical">
<EditText android:id="@+id/principal" android:hint="Principal"/>
<EditText android:id="@+id/rate" android:hint="Rate (%)"/>
<EditText android:id="@+id/time" android:hint="Time (years)"/>
<Button android:id="@+id/calculate" android:text="Calculate"/>
</LinearLayout>
Java Code:
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.custom_dialog);
EditText principal = dialog.findViewById(R.id.principal);
Button calculate = dialog.findViewById(R.id.calculate);
calculate.setOnClickListener(v -> {
double p = Double.parseDouble(principal.getText().toString());
double r = 10; // Default rate
double t = 1; // Default time
double interest = (p * r * t) / 100;
Toast.makeText(this, "Interest: " + interest, Toast.LENGTH_SHORT).show();
dialog.dismiss();
});
dialog.show();
Visual: Custom Dialog State After Input
Principal: 1000
Rate: 10%
Time: 1 year
Button: Calculate
1.3 Progress Dialogs
Show loading indicators for async tasks (e.g., API calls, file downloads).
Example:
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Loading");
progressDialog.setMessage("Please wait...");
progressDialog.setCancelable(false); // Prevent dismissal
progressDialog.show();
// Simulate async task
new Thread(() -> {
try { Thread.sleep(3000); }
catch (InterruptedException e) {}
runOnUiThread(() -> progressDialog.dismiss());
}).start();
Visual: Progress Dialog Lifecycle
sequenceDiagram
participant User
participant App
User->>App: Clicks "Download"
App->>App: Show ProgressDialog
App->>App: Start Async Task
App->>User: Dismiss Dialog (on completion)2. Menus in Android
Menus provide quick access to app features without cluttering the UI.
2.1 Options Menu (Toolbar Menu)
Appears when the user clicks the overflow icon (⋮) in the app bar.
XML (res/menu/options_menu.xml):
<menu xmlns:android="...">
<item android:id="@+id/action_settings" android:title="Settings"/>
<item android:id="@+id/action_help" android:title="Help"/>
</menu>
Java Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Visual: Options Menu Trigger
flowchart TD
A["User clicks ⋮"] --> B{"Options Menu"}
B -->|"Settings"| C["Open Settings Activity"]
B -->|"Help"| D["Show Help Dialog"]2.2 Context Menu (Long-Click Menu)
Appears when the user long-clicks a view (e.g., a list item).
Java Code:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
String selectedItem = listView.getItemAtPosition(info.position).toString();
switch (item.getItemId()) {
case R.id.action_delete:
Toast.makeText(this, "Deleted: " + selectedItem, Toast.LENGTH_SHORT).show();
return true;
default:
return super.onContextItemSelected(item);
}
}
XML (res/menu/context_menu.xml):
<menu xmlns:android="...">
<item android:id="@+id/action_delete" android:title="Delete"/>
<item android:id="@+id/action_edit" android:title="Edit"/>
</menu>
Visual: Context Menu Activation
sequenceDiagram
participant User
participant ListView
User->>ListView: Long-click Item
ListView->>App: Show Context Menu
User->>App: Select "Delete"
App->>ListView: Remove Item2.3 Popup Menu
A floating menu that appears when the user clicks a button (e.g., "More options").
Java Code:
Button popupButton = findViewById(R.id.popup_button);
popupButton.setOnClickListener(v -> {
PopupMenu popup = new PopupMenu(this, popupButton);
popup.inflate(R.menu.popup_menu);
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.action_copy:
Toast.makeText(this, "Copied", Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
});
popup.show();
});
XML (res/menu/popup_menu.xml):
<menu xmlns:android="...">
<item android:id="@+id/action_copy" android:title="Copy"/>
<item android:id="@+id/action_paste" android:title="Paste"/>
</menu>
Visual: Popup Menu Trigger
flowchart TD
A["User clicks Button"] --> B{"Popup Menu"}
B -->|"Copy"| C["Copy Text to Clipboard"]
B -->|"Paste"| D["Paste from Clipboard"]
B -->|"Delete"| E["Remove Selected Item"]
C --> F["Show Toast 'Copied!'"]
D --> F3. User Input Methods
Beyond dialogs and menus, Android provides widgets for direct input.
3.1 EditText with Validation
EditText emailEditText = findViewById(R.id.email);
Button submitButton = findViewById(R.id.submit);
submitButton.setOnClickListener(v -> {
String email = emailEditText.getText().toString();
if (email.matches("^[\\w.-]+@[\\w.-]+\\.[a-z]{2,}$")) {
Toast.makeText(this, "Valid email!", Toast.LENGTH_SHORT).show();
} else {
emailEditText.setError("Invalid email");
}
});
Visual: Input Validation Flow
flowchart TD
A["User enters email"] --> B{"Regex Check"}
B -->|"Valid"| C["Show Toast 'Valid'"]
B -->|"Invalid"| D["Show Error"]3.2 Spinners for Dropdown Lists
Spinner spinner = findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.countries, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
```figure
{"type":"array","values":["Nepal","India","Bangladesh","China"],"highlight":[1],"caption":"Spinner adapter state showing selected country (India) with array adapter"}
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { Toast.makeText(this, "Selected: " + parent.getItemAtPosition(pos), Toast.LENGTH_SHORT).show(); } // ... onNothingSelected });
**XML (`res/array/colors.xml`):**
```xml
<string-array name="colors">
<item>Red</item>
<item>Green</item>
<item>Blue</item>
</string-array>
Visual: Spinner State
Selected: Green
4. Toast Notifications
Short-lived messages for non-critical feedback (e.g., "Item added to cart").
Example:
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
Visual: Toast Lifecycle
5. View Binding vs. findViewById
| Feature | findViewById (Legacy) |
View Binding (Recommended) |
|---|---|---|
| Boilerplate | Manual casting | Auto-generated bindings |
| Null Safety | Risk of NPE | Compile-time checks |
| Performance | Slightly slower | Faster (no repeated lookups) |
| Example | Button btn = (Button) findViewById(R.id.button); |
Button btn = binding.button; |
Enable View Binding in build.gradle:
android {
...
buildFeatures {
viewBinding true
}
}
In the Real World
eSewa’s Transaction Confirmation
- Idea Used: Alert Dialog
- How: After a payment, eSewa shows a confirmation dialog with "OK" to proceed or "Cancel" to retry. This prevents accidental exits during high-value transactions.
- Worked Example: If a user pays ₹500, the app displays:
Transaction Successful! Amount: ₹500 [OK] [Cancel]
Pathao’s Route Selection
- Idea Used: Popup Menu
- How: When a user selects a pickup location, Pathao shows a popup menu with options like "Change Pickup," "Add Stop," or "Confirm Ride." This avoids cluttering the main screen.
- Worked Example: Tapping the pickup address icon triggers:
[Change Pickup] [Add Stop] [Confirm]
Ncell’s Data Plan Upgrade
- Idea Used: Custom Dialog + Spinner
- How: When a user taps "Upgrade Plan," Ncell opens a custom dialog with a spinner for plan options (e.g., 1GB, 5GB, 10GB) and a slider to adjust validity (1 month, 3 months). This replaces a long list with interactive controls.
- Worked Example:
Select Plan: [1GB] [5GB] [10GB] Validity: [1M] [3M] [6M] [Upgrade] [Cancel]
Exam Tip
- Dialogs (40%): Focus on custom dialogs (they appear in 60% of past exam questions). Practice combining XML layouts with Java logic (e.g., interest calculator).
- Menus (30%): Know the difference between options, context, and popup menus. Always include a
MenuInflaterandonMenuItemSelectedin your code. - Input Validation (20%): Use regex for emails/phone numbers and Toast for feedback. Example:
if (!email.matches("^[\\w.-]+@[\\w.-]+\\.[a-z]{2,}$")) { Toast.makeText(this, "Invalid email", Toast.LENGTH_SHORT).show(); } - View Binding (10%): Prefer
viewBindingoverfindViewByIdin exams. Mention its advantages in your answer. - Past Exam Patterns:
- 2018: Custom dialog for student details (ListView + custom dialog).
- 2020: Options menu with color-changing items.
- 2022: Alert dialog for factorial calculation + Toast output.
Pro Tip: For practical exams, always:
- Use XML for layouts (e.g.,
custom_dialog.xml). - Show state changes in your code (e.g., "After user taps 'Calculate,' the dialog calculates interest").
- Include error handling (e.g.,
try-catchfor parsing inputs).
Based on the TU BCA syllabus for Mobile Programming (CACS351), unit 5.
Discussion
Loading…