···
import 'dart:math' as math;
3
+
import 'dart:ui' show FlutterView;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
···
bool _authInvalidated = false;
double _lastKeyboardHeight = 0;
Timer? _bannerDismissTimer;
71
+
FlutterView? _cachedView;
···
98
+
void didChangeDependencies() {
99
+
super.didChangeDependencies();
100
+
// Cache the view reference so we can safely use it in didChangeMetrics
101
+
// even when the widget is being deactivated
102
+
_cachedView = View.of(context);
void _setupAuthListener() {
context.read<AuthProvider>().addListener(_onAuthChanged);
···
super.didChangeMetrics();
// Guard against being called after widget is deactivated
// (can happen during keyboard animation while navigating away)
154
-
if (!mounted) return;
164
+
if (!mounted || _cachedView == null) return;
156
-
final keyboardHeight = View.of(context).viewInsets.bottom;
166
+
final keyboardHeight = _cachedView!.viewInsets.bottom;
// Detect keyboard closing and unfocus text field
if (_lastKeyboardHeight > 0 && keyboardHeight == 0) {
···
with WidgetsBindingObserver {
final ValueNotifier<double> _keyboardMarginNotifier = ValueNotifier(0);
final ValueNotifier<double> _safeAreaBottomNotifier = ValueNotifier(0);
508
+
FlutterView? _cachedView;
···
void didChangeDependencies() {
super.didChangeDependencies();
519
+
// Cache view reference for safe access in didChangeMetrics
520
+
_cachedView = View.of(context);
···
void didChangeMetrics() {
534
+
// Schedule update after frame to ensure context is valid
535
+
WidgetsBinding.instance.addPostFrameCallback((_) {
541
+
if (!mounted || _cachedView == null) {
528
-
final view = View.of(context);
544
+
final view = _cachedView!;
final devicePixelRatio = view.devicePixelRatio;
final keyboardInset = view.viewInsets.bottom / devicePixelRatio;
final viewPaddingBottom = view.viewPadding.bottom / devicePixelRatio;