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.
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 noteKey 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!");
}
}
Method 2: Using ViewModel (Recommended)
// 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"| ACode 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
ListFragmentshows order history; tapping an item loads aDetailFragmentwith shipping updates. - Worked Example:
- User taps "Order #123" →
ListFragmentreplaces withDetailFragmentshowing:Order #123: Processing Status: Shipped (2/5)
- User taps "Order #123" →
3. Khalti (Payment Methods)
- Idea Used: Fragments for tabbed payment options (credit card, UPI, wallet).
- How: A
ViewPagerhosts fragments for each payment type, swapped via touch gestures.
9. Exam Tips
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."
- Know
Practice Fragment Transactions:
- Code a
FragmentTransactionto add/replace/remove fragments. - Example: "Write Java code to replace FragmentA with FragmentB when a button is clicked."
- Code a
Navigation Component:
- Understand
nav_graph.xmlandNavController. - Example: "Draw a navigation graph for an app with 3 screens (Home → Settings → Profile)."
- Understand
Data Passing:
- Use
BundleorViewModelfor fragment communication. - Example: "How would you pass a user ID from FragmentA to FragmentB?"
- Use
Common Pitfalls:
- Avoid memory leaks by properly detaching fragments.
- Use
addToBackStack()for navigable transitions.
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…