CACS351 Mobile Programming

Mobile ProgrammingUnit 412 min read

Views, Layouts & Widgets: UI Design in Android/iOS

Unit 4 of Mobile Programming: Explores how to build interactive user interfaces in Android (XML layouts, widgets, event handling) and iOS (Swift UI hierarchy), with practical examples like calculators, menus, and data displays—key for apps like Daraz’s product grids or Pathao’s ride booking screens.

TAKEAWAYS

  • Views are UI elements (buttons, text fields) that respond to user input; layouts (Linear, Relative, Constraint) organize them hierarchically.
  • Widgets (EditText, ImageView, Spinner) handle input/output; adapters (ArrayAdapter, RecyclerView) dynamically populate lists.
  • Event handling uses onClick, onTouch, and listeners to trigger actions (e.g., Pathao’s “Confirm Ride” button).
  • iOS Swift mirrors Android’s concepts but uses UIView/UIStackView and SwiftUI’s declarative syntax.
  • JSON integration (e.g., Daraz’s product APIs) requires parsing into views like ImageView or TextView.
  • Performance tip: Prefer RecyclerView over ListView for large datasets (e.g., YouTube’s video thumbnails).

1. Core Concepts: Views, Layouts, and Widgets

1.1 What is a View?

A View is the smallest building block of an Android/iOS UI—anything the user interacts with or sees:

  • TextView (static/dynamic text)
  • Button (clickable actions)
  • ImageView (displays images)
  • EditText (user input fields)

FIGURE 1: Android View Hierarchy

mindmap
  root((View Hierarchy))
    AndroidView["AndroidView\n(extends View)"]
      - TextView["Displays text\n(e.g., labels, messages)"]
      - Button["Clickable action\n(e.g., 'Submit')" ]
      - ImageView["Shows images\n(e.g., app icons)"]
      - EditText["User input\n(e.g., login fields)"]
    iOSView["iOSView\n(UIView)"]
      - UILabel["Static text\n(e.g., 'Price:')" ]
      - UIButton["Tap actions\n(e.g., 'Buy Now')" ]
      - UIImageView["Image display\n(e.g., product thumbnails)"]
      - UITextField["Input fields\n(e.g., search bars)"]

Key Idea: Views are instantiated in code (Android: XML/Java/Kotlin; iOS: Swift) and drawn on the screen via the View Hierarchy Tree.


1.2 Layouts: Organizing Views

Layouts define how views are arranged spatially. Android offers:

  • LinearLayout: Views stacked horizontally or vertically (default).
  • RelativeLayout: Views positioned relative to each other (e.g., a button below an image).
  • ConstraintLayout: Modern alternative for complex UI (used in Pathao’s ride details).
  • GridLayout: Views in a grid (e.g., Daraz’s product catalog).

FIGURE 2: LinearLayout vs. RelativeLayout

flowchart TD
    A["LinearLayout
(Vertical)"] --> B["View1
(TextView)"]
    B --> C["View2
(Button)"]
    C --> D["View3
(ImageView)"]

    E["RelativeLayout"] --> F["ViewA
(ImageView)
android:layout_below="@+id/ViewB"]
    E --> G["ViewB
(TextView)"]
    E --> H["ViewC
(Button)
android:layout_alignParentBottom="true"]

    I["ConstraintLayout
(Modern)"] --> J["ViewX
(Button)
constraint: "end_to_start=ViewY.start"]
    I --> K["ViewY
(TextView)
constraint: "start=parent.start, end=parent.end"]

Example: A simple calculator (multiplication/division) uses LinearLayout:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/num1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Enter first number"/>

    <EditText
        android:id="@+id/num2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Enter second number"/>

    <Button
        android:id="@+id/multiply"
        android:text="Multiply"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/divide"
        android:text="Divide"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

Trace: When the user clicks “Multiply”, the app reads num1 and num2, computes the product, and updates result.


1.3 Widgets: Functional UI Components

Widgets extend views with specific behaviors:

Widget Purpose Example Use Case
EditText User input (text) Pathao’s “Enter destination” field
Spinner Dropdown list Daraz’s “Sort by: Price/Rating”
CheckBox Binary choice (on/off) eSewa’s “Remember me” checkbox
RadioButton Single-choice group Ncell’s “Plan selection” radio buttons
ProgressBar Loading indicator YouTube’s video buffering

FIGURE 3: Spinner Widget in Action

flowchart TD
    A["Spinner
(android.widget.Spinner)"] --> B["ArrayAdapter
(links data to Spinner)"]
    B --> C["onItemSelectedListener
(triggers action)"]
    C --> D["Display selected item
(e.g., 'Ncell' plan)"]

    E["CheckBox
(eSewa)"] --> F["isChecked("")
Boolean state"]
    G["RadioGroup
(Ncell)"] --> H["getCheckedRadioButtonId("")
Single selection"]
    I["ProgressBar
(YouTube)"] --> J["setProgress("")
Dynamic updates"]

Worked Example: A bank loan calculator uses Spinner for interest rates:

val interestRates = arrayOf("5%", "7%", "9%")
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, interestRates)
spinnerInterestRate.adapter = adapter

spinnerInterestRate.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
        val rate = interestRates[position]
        // Update loan calculation logic
    }
    override fun onNothingSelected(parent: AdapterView<*>) {}
}

2. Event Handling: Making Views Interactive

Views respond to user actions via listeners:

  • Click events: onClick (buttons, images)
  • Touch events: onTouch (swipes, drags)
  • Text changes: AddTextChangedListener (EditText)

FIGURE 4: Button Click Event Flow

sequenceDiagram
    participant User
    participant Button
    participant MainActivity

    User->>Button: Clicks "Calculate"
    Button->>MainActivity: onClick() callback
    MainActivity->>MainActivity: Reads EditText values
    MainActivity->>MainActivity: Computes result
    MainActivity->>TextView: Updates display

Code Example: Handling a color-changing menu (exam question):

button.setOnClickListener {
    when (menuItemSelected) {
        "Red" -> rootLayout.setBackgroundColor(Color.RED)
        "Blue" -> rootLayout.setBackgroundColor(Color.BLUE)
        // ... other colors
    }
}

3. Lists and Adapters: Dynamic Data Display

3.1 ListView vs. RecyclerView

Feature ListView RecyclerView
Performance Slower (creates new views) Faster (recycles views)
Flexibility Limited High (custom layouts, animations)
Use Case Small, static lists Large datasets (e.g., YouTube videos)

FIGURE 5: RecyclerView vs. ListView

022.54567.590ListView30RecyclerView90% Performance Efficiency (Relative)
Performance comparison: ListView creates new views per item, while RecyclerView reuses them.

Worked Example: Displaying 10 fruit images in a 2-column GridView:

<GridView
    android:id="@+id/fruitGrid"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:numColumns="2"
    android:gravity="center"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="100dp"
        android:layout_height="100dp"/>
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

Adapter Code:

val fruits = listOf("Apple", "Banana", "Cherry", ...)
val adapter = ArrayAdapter(this, R.layout.fruit_item, fruits)
fruitGrid.adapter = adapter

3.2 JSON Integration: Fetching Data

Apps like Daraz use JSON APIs to fetch product data. Example:

{
  "products": [
    {"id": 1, "name": "Laptop", "price": 50000},
    {"id": 2, "name": "Phone", "price": 25000}
  ]
}

Parsing JSON in Android:

val jsonString = "{\"products\": [{\"name\": \"Laptop\", \"price\": 50000}]}"
val jsonObject = JSONObject(jsonString)
val products = jsonObject.getJSONArray("products")
for (i in 0 until products.length()) {
    val product = products.getJSONObject(i)
    val name = product.getString("name")
    val price = product.getInt("price")
    // Update RecyclerView
}

4. iOS Equivalents: SwiftUI and UIKit

Android Concept iOS Equivalent Swift Code Example
LinearLayout UIStackView let stackView = UIStackView()
RelativeLayout Auto Layout Constraints view.addConstraint(...)
Button UIButton let button = UIButton(type: .system)
RecyclerView UITableView/UICollectionView tableView.register(...)
JSON Parsing JSONSerialization let data = try JSONSerialization.data(...)

Swift Example: Factorial calculation (exam question):

func factorial(of n: Int) -> Int {
    if n == 0 { return 1 }
    return n * factorial(of: n - 1)
}
print(factorial(of: 5)) // Output: 120

5. Real-World Applications

Pathao Ride DetailsDaraz Product GridYouTube Video List
Real-world apps using the layouts/widgets discussed.

## In the real world

  1. Pathao’s Ride Booking:

    • Layout: Uses ConstraintLayout to dynamically adjust UI for ride details (pickup/drop-off addresses, fare).
    • Widget: Spinner for selecting ride type (bike, car, premium).
    • Event: onClick on “Confirm Ride” button triggers payment processing via eSewa/Khalti API.
  2. Daraz’s Product Grid:

    • RecyclerView: Displays thousands of products efficiently (recycles view holders).
    • JSON: Fetches product data from Daraz’s backend API and updates the grid in real time.
  3. Ncell’s Plan Selection:

    • RadioButton Group: Users select a plan (e.g., “Ncell 1GB”); the app calculates monthly cost dynamically.

Worked Example: NTC’s Traffic Route App

  • Layout: RelativeLayout positions a map (MapView) with a “Current Location” button below it.
  • Event: Clicking the button updates the map’s center using GPS coordinates (via LocationManager).
  • JSON: Fetches traffic data from NTC’s API and highlights congested routes in red.

6. Exam Tips

  • Views vs. Layouts:

    • Views = individual UI elements (e.g., Button).
    • Layouts = containers that organize views (e.g., LinearLayout).
    • Exam trick: Always mention hierarchy (e.g., “The Button is inside a LinearLayout”).
  • Adapters:

    • ArrayAdapter → Simple lists (e.g., Spinner).
    • RecyclerView.Adapter → Complex lists (e.g., YouTube thumbnails).
    • Exam trick: Draw a state diagram of how data binds to views.
  • JSON Parsing:

    • Always show before/after parsing states:
      // Before
      {"users": [{"name": "Alice", "age": 25}]}
      
      // After (Swift/Kotlin)
      let user = User(name: "Alice", age: 25)
      
    • Exam trick: Link JSON keys to specific views (e.g., "name" → TextView).
  • iOS Swift:

    • Compare Android XML vs. SwiftUI declarative code.
    • Example: A TextView in Android vs. Text("Hello") in SwiftUI.
  • Performance:

    • Always prefer RecyclerView over ListView for large datasets.
    • Exam trick: Mention view recycling as the key advantage.

Final Note: For practical exams, develop a calculator app (as in the syllabus) or a menu-driven app (e.g., color changer). Use screenshots of your UI in the answer to score full marks.

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

Discussion

Loading…