Skip to content

fix(android): implement automatic edge-to-edge and universal keyboard handling#8366

Open
fabiomartino wants to merge 5 commits intoionic-team:mainfrom
fabiomartino:fix/safe-area_edge2edge
Open

fix(android): implement automatic edge-to-edge and universal keyboard handling#8366
fabiomartino wants to merge 5 commits intoionic-team:mainfrom
fabiomartino:fix/safe-area_edge2edge

Conversation

@fabiomartino
Copy link

Summary

This PR implements universal safe-area and edge-to-edge support for Android, resolving issues where the implementation was gated to Android 15+ only (VANILLA_ICE_CREAM). The fix works on Android 6+ (API 21+) while maintaining backward compatibility.

Key Changes

  1. Removed Android 15+ restriction: Changed Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM to MIN_INSETS_VERSION = Build.VERSION_CODES.LOLLIPOP (API 21)

  2. Automatic edge-to-edge: Added enableEdgeToEdgeIfNeeded() method using reflection to call androidx.activity.EdgeToEdge.enable() - no MainActivity modification required

  3. Improved broken WebView handling:

    • WebView < 140: uses native bottom margin + CSS bottom = 0 to avoid double-inset
    • WebView >= 140: uses standard CSS safe-area approach
  4. Lifecycle fixes:

    • Added handleOnResume() to re-apply insets after returning from external activities
    • Added defensive reset when viewport-fit=cover is not present
  5. Universal keyboard handling: IME visibility is now monitored on ALL Android versions (not just 15+)

Issues Resolved

Testing

Tested on:

  • Android 14 (API 34)
  • Android 13 (API 33)
  • Android 12 (API 31)
  • Android 11 (API 30)
  • WebView >= 140 - CSS safe-area approach
  • WebView < 140 - native margin fallback

Behavior

WebView >= 140

  • CSS variables --safe-area-inset-* are injected with correct values
  • No native margin/padding applied to parent view

WebView < 140 (Broken WebView)

  • Native bottom margin applied to parent view
  • CSS --safe-area-inset-bottom forced to 0 (to avoid double-offset with fixed footers)
  • More aggressive inset handling to compensate for WebView bugs

Keyboard State

  • When keyboard is visible, bottom inset is correctly calculated
  • --safe-area-inset-bottom reflects keyboard height

Configuration

Default configuration works automatically. Optional configuration in capacitor.config.ts:

plugins: {
  SystemBars: {
    insetsHandling: 'css',  // 'css' | 'disable'
    style: 'DARK',        // 'DARK' | 'LIGHT' | 'DEFAULT'
  },
}

Breaking Changes

None. This is a bug fix that expands functionality to older Android versions while maintaining existing behavior on Android 15+.

Migration

No migration required. Existing configurations continue to work.

Additional Notes

  • Uses reflection for EdgeToEdge.enable() to maintain backward compatibility without requiring additional dependencies
  • Gracefully handles cases where EdgeToEdge class is not available

@derWebdesigner
Copy link

@fabiomartino Thank you so much Fabio. This is such a crucial fix I'm waiting for. 🙏

@theproducer theproducer self-assigned this Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants