CACS351 Mobile Programming

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 Item

2.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 --> F

3. 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

  1. 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]
      
  2. 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]
      
  3. 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 MenuInflater and onMenuItemSelected in 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 viewBinding over findViewById in 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:

  1. Use XML for layouts (e.g., custom_dialog.xml).
  2. Show state changes in your code (e.g., "After user taps 'Calculate,' the dialog calculates interest").
  3. Include error handling (e.g., try-catch for parsing inputs).

Based on the TU BCA syllabus for Mobile Programming (CACS351), unit 5.

Discussion

Loading…