CACS351 Mobile Programming

Mobile ProgrammingUnit 710 min read

Fragments & Navigation: Modular UI & Flow Control

Unit 7 of Mobile Programming: Explains how fragments enable reusable UI components, dynamic navigation between screens, and efficient resource management in Android apps, with hands-on code for fragment lifecycle, communication, and navigation patterns.

TAKEAWAYS:

  • Fragments are modular UI components that can be combined in activities to create flexible layouts (e.g., a settings panel or a map view).
  • Navigation components (NavGraph, NavController) simplify screen transitions with deep linking and back stack management.
  • Fragment transactions (add/remove/replace) control dynamic UI updates without restarting activities.
  • Data sharing between fragments uses interfaces, ViewModel, or Bundle objects.
  • Fragments reduce code duplication and improve app scalability compared to single-activity designs.
  • Real-world use: Pathao uses fragments for modular ride options (car, bike, van) and Khalti for payment method selection tabs.

1. What is a Fragment?

A fragment is a modular piece of an activity’s UI and behavior. Unlike activities, fragments:

  • Cannot run independently.
  • Must be hosted inside an activity.
  • Can be dynamically added/removed/replaced.
Activity0FragmentA1FragmentB2FragmentC3
A typical Activity hosting multiple Fragments for modular UI components

Key Characteristics

mindmap
  root((Fragment))
    - Modular UI
      - Reusable components (e.g., settings panel, map)
    - Lifecycle
      - Tied to host activity
      - `onAttach()`, `onCreate()`, `onStart()`, `onResume()`, `onPause()`, `onStop()`, `onDestroy()`
    - Communication
      - Data passed via `Bundle` or interfaces
      - EventBus/SharedViewModel for complex apps
    - Navigation
      - Managed via `FragmentTransaction`
      - Modern: `NavController` + `NavigationGraph`

Fragment vs. Activity

Feature Fragment Activity
Independence Depends on activity Independent process
UI Scope Part of activity’s layout Full-screen UI
Lifecycle Follows activity’s state Has its own lifecycle
Use Case Reusable components (e.g., tabs) Main app screens

2. Creating and Managing Fragments

Step 1: Define a Fragment Class

public class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
}

Layout (fragment_my.xml):

<LinearLayout xmlns:android="...">
    <TextView android:text="Hello Fragment!" />
</LinearLayout>

Step 2: Add Fragment to Activity

// In Activity’s onCreate()
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_container, new MyFragment());
ft.commit();

Visual: Fragment Hosting in Activity

┌───────────────────────────────┐
│   Activity Layout             │
│   ┌─────────────────────────┐ │
│   │ Fragment Container      │ │ ← Hosts fragments dynamically
│   └─────────────────────────┘ │
└───────────────────────────────┘

3. Fragment Lifecycle

Fragments share the activity’s lifecycle but have their own callbacks:

stateDiagram-v2
    [*] --> Created
    Created --> Started
    Started --> Resumed
    Resumed --> Paused
    Paused --> Stopped
    Stopped --> Destroyed
    Destroyed --> [*]
    note right of Created
      `onAttach()`, `onCreate()`
    end note
    note right of Started
      `onStart()`
    end note
    note right of Resumed
      `onResume()`
    end note

Key Methods:

  • onAttach(): Fragment binds to activity.
  • onCreate(): Initializes views.
  • onDestroyView(): Called when fragment’s view is removed.

4. Fragment Transactions

Use FragmentTransaction to manage fragments:

// Replace fragment
ft.replace(R.id.container, new FragmentB());

// Add fragment (stacked)
ft.add(R.id.container, new FragmentB(), "tag");

// Remove fragment
ft.remove(fragment);

// Commit transaction
ft.commit();

Visual: Fragment Replacement

Before:
┌───────────────────────────────┐
│   Activity                    │
│   ┌─────────────────────────┐ │
│   │ FragmentA               │ │
│   └─────────────────────────┘ │
└───────────────────────────────┘

After ft.replace():
┌───────────────────────────────┐
│   Activity                    │
│   ┌─────────────────────────┐ │
│   │ FragmentB               │ │
│   └─────────────────────────┘ │
└───────────────────────────────┘

5. Communicating Between Fragments

Method 1: Using Interfaces

// FragmentA.java
public interface OnFragmentAListener {
    void sendData(String data);
}

// FragmentB.java
public class FragmentB extends Fragment {
    OnFragmentAListener listener;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        listener = (OnFragmentAListener) context;
    }
    public void sendData() {
        listener.sendData("Hello from FragmentB!");
    }
}
// SharedViewModel.java
public class SharedViewModel extends AndroidViewModel {
    private MutableLiveData<String> data = new MutableLiveData<>();
    public void setData(String value) { data.setValue(value); }
    public LiveData<String> getData() { return data; }
}

6. Navigation Components (Modern Approach)

Android’s Navigation Component simplifies fragment transitions:

<!-- nav_graph.xml -->
<navigation xmlns:android="...">
    <fragment android:id="@+id/fragmentA" android:name="FragmentA" />
    <fragment android:id="@+id/fragmentB" android:name="FragmentB" />
    <action android:id="@+id/actionA_to_B"
            app:destination="@id/fragmentB" />
</navigation>

Visual: Navigation Graph

graph TD
    A["FragmentA"] -->|"Click Button"| B["FragmentB"]
    B -->|"Back"| A
[object Object][object Object][object Object]FragmentAFragmentBFragmentCSettingsFragment
Navigation flow in a modern Android app using Navigation Component

Code to Initialize:

NavController navController = Navigation.findNavController(this, R.id.nav_host);
navController.navigate(R.id.actionA_to_B);

7. Worked Example: Student List with Fragment

Goal: Display students in a ListView and show details in a fragment.

Step 1: ListView Activity

public class StudentListActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        ListView listView = findViewById(R.id.student_list);
        List<String> students = Arrays.asList("Alice", "Bob", "Charlie");
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, students);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener((parent, view, position, id) -> {
            String selected = students.get(position);
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.fragment_container, StudentDetailFragment.newInstance(selected));
            ft.addToBackStack(null);
            ft.commit();
        });
    }
}

Step 2: Detail Fragment

public class StudentDetailFragment extends Fragment {
    public static StudentDetailFragment newInstance(String name) {
        Bundle args = new Bundle();
        args.putString("student_name", name);
        StudentDetailFragment fragment = new StudentDetailFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_detail, container, false);
        TextView textView = view.findViewById(R.id.detail_text);
        textView.setText("Details for: " + getArguments().getString("student_name"));
        return view;
    }
}

Visual: Fragment Transition

Before Click:
┌───────────────────────────────┐
│   ListView Activity           │
│   ┌─────────────────────────┐ │
│   │ [Alice] [Bob] [Charlie] │ │
│   └─────────────────────────┘ │
└───────────────────────────────┘

After Click:
┌───────────────────────────────┐
│   ListView Activity           │
│   ┌─────────────────────────┐ │
│   │ [Alice] [Bob] [Charlie] │ │ ← Back stack
│   └─────────────────────────┘ │
│   ┌─────────────────────────┐ │
│   │ Fragment: Alice Details  │ │ ← New fragment
│   └─────────────────────────┘ │
└───────────────────────────────┘

8. Real-World Applications

1. Pathao (Ride Options)

  • Idea Used: Fragments for modular ride selection (car, bike, van).
  • How: Each ride type is a fragment swapped dynamically based on user choice.
  • Visual:
    flowchart TD
        A["Main Activity"] --> B["Fragment: Car Ride"]
        A --> C["Fragment: Bike Ride"]
        A --> D["Fragment: Van Ride"]

2. Daraz (Order Queue)

  • Idea Used: Fragments for order status tracking.
  • How: A ListFragment shows order history; tapping an item loads a DetailFragment with shipping updates.
  • Worked Example:
    • User taps "Order #123" → ListFragment replaces with DetailFragment showing:
      Order #123: Processing
      Status: Shipped (2/5)
      

3. Khalti (Payment Methods)

  • Idea Used: Fragments for tabbed payment options (credit card, UPI, wallet).
  • How: A ViewPager hosts fragments for each payment type, swapped via touch gestures.

9. Exam Tips

  1. Focus on Fragment Lifecycle:

    • Know onAttach(), onCreate(), onDestroyView() and their order.
    • Example question: "Explain the lifecycle of a fragment when its host activity is paused."
  2. Practice Fragment Transactions:

    • Code a FragmentTransaction to add/replace/remove fragments.
    • Example: "Write Java code to replace FragmentA with FragmentB when a button is clicked."
  3. Navigation Component:

    • Understand nav_graph.xml and NavController.
    • Example: "Draw a navigation graph for an app with 3 screens (Home → Settings → Profile)."
  4. Data Passing:

    • Use Bundle or ViewModel for fragment communication.
    • Example: "How would you pass a user ID from FragmentA to FragmentB?"
  5. Common Pitfalls:

    • Avoid memory leaks by properly detaching fragments.
    • Use addToBackStack() for navigable transitions.
  6. Real-World Mapping:

    • Relate fragments to apps like Pathao (modular UI) or Khalti (tabbed layouts).
    • Example: "Explain how Daraz uses fragments to show order details dynamically."

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

Discussion

Loading…