Skip to content

BottomSheetBehavior ignores child View heights when calculating position (OPPO ColorOS Android 16) #5080

@manakov892025-byte

Description

@manakov892025-byte

BottomSheetBehavior does not account for child View heights (including spacers) when calculating its position, causing it to overlap system navigation bar on devices with incorrect WindowInsets values.

Expected behavior

When a spacer View is added to the bottom of BottomSheet content with a specific height, BottomSheetBehavior should position itself to accommodate that spacer, keeping all content visible above the navigation bar.

Actual behavior

BottomSheetBehavior ignores the spacer View height and positions itself based only on WindowInsets values, even when those values are incorrect.

Device Information

  • Device: OPPO A5 Pro (CPH2711)
  • Android: 16 (API 36)
  • OS: ColorOS
  • Material Components: 1.9.0

Root Cause

ColorOS on Android 16 reports incorrect WindowInsets.bottom value (88px instead of ~720px). While this is a ColorOS bug, BottomSheetBehavior has no fallback mechanism to handle incorrect system values.

Reproduction

Layout

<LinearLayout
    android:id="@+id/bottomSheetContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    
    <!-- Content -->
    
    <View
        android:id="@+id/spacer"
        android:layout_width="match_parent"
        android:layout_height="0dp" />
</LinearLayout>

Code

ViewCompat.setOnApplyWindowInsetsListener(bottomSheet) { view, insets ->
    val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
    
    // Set spacer height to correct value
    val spacer = view.findViewById<View>(R.id.spacer)
    val params = spacer.layoutParams
    params.height = 480 // Correct value
    spacer.layoutParams = params
    
    insets
}

val behavior = BottomSheetBehavior.from(bottomSheet)
// BottomSheet still overlaps navigation bar despite spacer

Logs

WindowInsets: Bottom inset detected: 88px (WRONG)
WindowInsets: Spacer height set to: 480px (CORRECT)
Result: BottomSheet overlaps navigation bar (spacer ignored)

Workarounds Attempted

  1. paddingBottom - ignored by BottomSheetBehavior ❌
  2. layout_marginBottom - creates gap but doesn't fix positioning ❌
  3. Spacer View - ignored by BottomSheetBehavior ❌
  4. fitsSystemWindows="true" - no effect ❌

Proposed Solution

Option 1: Account for child heights

Modify BottomSheetBehavior to include child View heights in position calculation:

private fun calculatePosition() {
    val windowInsets = getWindowInsets()
    val childHeight = getTotalChildHeight() // Include all children
    val position = parentHeight - childHeight - windowInsets.bottom
    // ...
}

Option 2: Allow manual offset override

Add API to manually override WindowInsets:

behavior.setNavigationBarOffset(480) // Manual override

Option 3: Detect incorrect WindowInsets

Add validation for suspiciously small WindowInsets values:

private fun getNavigationBarInset(): Int {
    val systemInset = windowInsets.bottom
    
    // Validate: navigation bar is typically 48-96dp
    if (systemInset < 100 && Build.VERSION.SDK_INT >= 35) {
        // Suspicious value, use fallback
        return getFallbackNavigationBarHeight()
    }
    
    return systemInset
}

Impact

This issue affects:

  • All OPPO devices with ColorOS Android 16
  • Potentially other OEM skins with incorrect WindowInsets
  • Any app using BottomSheetBehavior with Edge-to-Edge design

Related Issues

  • ColorOS WindowInsets bug reported to OPPO
  • Android Framework bug reported to Google Issue Tracker

Additional Context

The issue does NOT occur on:

  • Android API 24-35 (all devices)
  • Android 16 on Google Pixel, Samsung devices
  • Only affects OPPO ColorOS Android 16

This suggests BottomSheetBehavior should be more resilient to incorrect system values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions