Android Development

Google's android guide Home Contact

Android Fragments

Fragments allow to divide the user interface of an activity into smaller, reusable components that can be combined in various ways to create a responsive UI for different screen sizes and orientations. On larger screens, such as tablets, multiple fragments can be displayed side by side in a multi-pane layout. Each fragment has its own layout and UI components, enabling code reusability across different screens. Fragments can also be dynamically added or removed from activities at runtime.

Adding Fragments to an Activity

There are two primary ways to add fragments to an activity:

  • Using the <fragment> tag: Define the fragment in the activity’s layout file using the <fragment> tag. The fragment is automatically attached to the activity when the layout is inflated.
  • Using a container view: Define a container view in the activity’s layout file, then programmatically add the fragment to the container using the FragmentManager and FragmentTransaction. This approach provides greater control over when and how the fragment is attached.

Fragments Lifecycle

Fragments have their own lifecycle methods, which allow developers to manage the state and behavior of each fragment independently. Below is a summary of the key lifecycle methods:

  • onAttach(): Called when the fragment is associated with an activity. Perform initial setup requiring access to the activity.
  • onCreate(): Perform one-time initialization, such as setting up variables and resources.
  • onCreateView(): Inflate the fragment's layout and return the root View representing the fragment's UI.
  • onViewCreated(): Perform additional UI setup after the View has been created.
  • onActivityCreated(): Interact with the hosting activity after its onCreate() has completed.
  • onStart(): Called when the fragment becomes visible. Use this to start or resume operations that need visibility.
  • onResume(): Called when the fragment is active and interacting with the user. Perform updates or start animations here.
  • onPause(): Pause operations or unregister callbacks when the fragment is no longer actively interacting with the user.
  • onStop(): Stop background tasks or UI operations when the fragment is no longer visible.
  • onDestroyView(): Clean up the View and resources associated with the fragment's UI.
  • onDestroy(): Release resources held by the fragment, such as context references.
  • onDetach(): Perform final cleanup when the fragment is disassociated from its hosting activity.

Note: Unlike activities, fragments do not have an onRecreate() method. When a parent activity is recreated (e.g., due to a configuration change), its fragments are also destroyed and recreated, following the same lifecycle sequence.

Fragments Communication

Fragments can exchange data with each other and with their hosting activity in various ways. The choice of method depends on the app's requirements and architecture.

  • Shared ViewModel: Use a ViewModel associated with the activity to hold shared data and state. Fragments can observe LiveData in the ViewModel to exchange data reactively.
  • Interfaces: Define callback interfaces in fragments that their hosting activity or other fragments implement. Use these interfaces to pass data between fragments.
  • Local Broadcasts: Use the Local Broadcast Manager to send and receive broadcasts within your app for communication between fragments.
  • Event Bus Libraries: Use third-party libraries like EventBus or Otto to facilitate event-driven communication between fragments and other app components.
  • SharedPreferences: Store and retrieve key-value pairs in SharedPreferences for simple data exchange.

Fragments with Jetpack

Jetpack Compose provides a declarative approach to building modern UI components, eliminating the need for fragments in many cases. Compose manages UI state and navigation effectively, offering a simpler and more cohesive development experience. However, fragments remain relevant for specific use cases, particularly when dealing with legacy codebases or complex integrations. Below are some scenarios where fragments may still be essential:

  • Interoperability with Legacy Code: In projects with existing fragments, migrating entirely to Compose might not be feasible. Fragments provide a bridge for embedding modern UI components into legacy architectures while incrementally adopting Compose.
  • Complex Multi-pane Layouts: On devices like tablets, fragments are useful for creating multi-pane layouts, allowing independent lifecycle management of each UI pane. Compose can replicate this functionality, but fragments provide a familiar and established approach for such use cases.
  • Lifecycle Management: Fragments come with built-in lifecycle methods and integration with Activity lifecycles. While Compose offers tools like `remember` and `LaunchedEffect`, fragments provide a more granular lifecycle control for tasks like resource cleanup and dynamic UI changes.
  • Integration with Non-Compose Components: When working with third-party libraries or native Android components that are not Compose-ready, fragments offer a straightforward way to integrate these components alongside a Compose-based UI. Using the AndroidView composable function, fragments can be embedded directly into the Compose hierarchy.
  • Navigation Architecture: The Jetpack Navigation Component relies heavily on fragments for managing navigation graphs in traditional View-based UIs. Although Compose offers its own navigation solution, fragments remain useful for hybrid projects or when leveraging features like deep linking and dynamic feature modules.