How to Enable Edge-to-Edge Display Only for Specific Fragment in Android with Bottom Navigation?

3 min read 01-09-2024
How to Enable Edge-to-Edge Display Only for Specific Fragment in Android with Bottom Navigation?


In the realm of Android app development, achieving a tailored user experience is crucial. One common requirement developers face is enabling edge-to-edge display for specific fragments while maintaining traditional UI behavior for others. In this article, we'll explore how to implement this functionality, particularly for a HomeFragment with a Bottom Navigation View.

Understanding Edge-to-Edge Display

Edge-to-edge display is a feature that allows your app to utilize the entire screen real estate, providing a more immersive experience. However, applying this mode to the base activity can lead to undesired results in fragments, as seen in a query on Stack Overflow where the user wanted edge-to-edge display only for their HomeFragment.

The Problem

As highlighted in the original Stack Overflow question, the user encountered a problem where enabling edge-to-edge mode in their base activity affected all fragments, and they sought a solution to limit this behavior to just one fragment. The user's code was structured to switch between three fragments using a Bottom Navigation View, but enabling the feature at the activity level caused unwanted effects in the other fragments.

The Solution

The solution involves programmatically controlling the edge-to-edge settings on a fragment-by-fragment basis. Here’s how to do this effectively.

Step 1: Define the Edge-to-Edge Mode

First, ensure that you define the edge-to-edge mode in your BaseActivity. However, instead of enabling it directly in onCreate, you will toggle it based on the currently displayed fragment.

Step 2: Modify the Fragment Switching Logic

Update the logic in your switchFragment method to check which fragment is currently active, and enable or disable edge-to-edge mode accordingly. Here's how you can achieve that:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(binding.root)
    setupBottomNavs()
}

private fun setupBottomNavs(){
    binding.bottomNav.selectedItemId = R.id.homeFragment // Set the default selected item to home
    setFragment(HomeFragment())
    binding.bottomNav.setOnItemSelectedListener(object : NavigationBarView.OnItemSelectedListener {
        override fun onNavigationItemSelected(newTab: MenuItem): Boolean {
            when (newTab.itemId) {
                R.id.homeFragment -> {
                    switchFragment(HomeFragment())
                    return true
                }
                R.id.ordersFragment -> {
                    switchFragment(OrdersFragment())
                    return true
                }
                R.id.saleFragment -> {
                    switchFragment(SaleFragment())
                    return true
                }
            }
            return false
        }
    })
}

private fun switchFragment(fragment: Fragment) {
    val transaction = supportFragmentManager.beginTransaction()
    // Hide all fragments
    for (existingFragment in supportFragmentManager.fragments) {
        transaction.hide(existingFragment)
    }
    
    var showFragment = supportFragmentManager.findFragmentByTag(fragment.javaClass.simpleName)
    if (showFragment == null) {
        showFragment = fragment
        transaction.add(R.id.frameLayout, showFragment, fragment.javaClass.simpleName)
    } else {
        transaction.show(showFragment)
    }
    
    transaction.commitAllowingStateLoss()
    
    // Check which fragment is displayed and enable/disable edge-to-edge
    when (showFragment) {
        is HomeFragment -> enableEdgeToEdge()
        else -> disableEdgeToEdge()
    }
}

private fun enableEdgeToEdge() {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or 
                                          View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or 
                                          View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}

private fun disableEdgeToEdge() {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
}

Explanation of the Code

  • Fragment Management: In the switchFragment method, we manage the visibility of existing fragments and determine which fragment to show based on the current selection.
  • System UI Visibility: The enableEdgeToEdge function modifies the system UI visibility to allow edge-to-edge display, while disableEdgeToEdge resets this setting.
  • Fragment Checks: The logic within switchFragment ensures that when the HomeFragment is displayed, edge-to-edge mode is enabled; otherwise, it is disabled for other fragments.

Practical Examples

To implement this in a real application, you might want to customize the user experience further. For instance, consider changing the status bar color or adding transition animations when switching between fragments. Also, ensure that your layouts adapt well to both edge-to-edge and non-edge-to-edge displays, especially in terms of padding and margins.

Conclusion

By following the steps outlined above, you can easily achieve an edge-to-edge display for specific fragments within an Android app while maintaining the default display behavior for others. This approach not only provides a better user experience but also allows for greater flexibility in UI design.

Feel free to explore more complex scenarios or integrate this pattern within your larger application architecture.

References

This comprehensive solution should empower you to create a dynamic and engaging Android application tailored to your users’ needs. Happy coding!