@@ -26,20 +26,20 @@ internal class SafeAreaHandler(View owner, Context context, Func<ICrossPlatformL
2626 bool ? _scrollViewDescendant ;
2727
2828 internal IOnApplyWindowInsetsListener GetWindowInsetsListener ( ) =>
29- new WindowInsetsListener ( this , ( ) => _owner . RequestLayout ( ) ) ;
29+ new WindowInsetsListener ( this ) ;
3030
3131 /// <summary>
3232 /// Forces a re-application of window insets when safe area configuration changes.
3333 /// This ensures OnApplyWindowInsets is called before measure and arrange.
3434 /// </summary>
3535 internal void InvalidateWindowInsets ( )
3636 {
37- if ( _lastReceivedInsets is not null )
37+ /* if (_lastReceivedInsets is not null)
3838 {
3939 // Re-apply the last received insets to trigger OnApplyWindowInsets
4040 ViewCompat.DispatchApplyWindowInsets(_owner, _lastReceivedInsets);
4141 }
42- else
42+ else*/
4343 {
4444 // Request fresh insets from the system
4545 ViewCompat . RequestApplyInsets ( _owner ) ;
@@ -164,10 +164,10 @@ bool ValidateSafeArea()
164164 internal void UpdateSafeAreaConfiguration ( )
165165 {
166166 // Clear cached ScrollView descendant check
167- _scrollViewDescendant = null ;
167+ // _scrollViewDescendant = null;
168168
169169 // Force re-calculation of safe area
170- var oldSafeArea = _safeArea ;
170+ // var oldSafeArea = _safeArea;
171171 _safeArea = GetAdjustedSafeAreaInsets ( ) ;
172172
173173 // Always invalidate insets when configuration changes, regardless of whether
@@ -194,10 +194,9 @@ internal static bool HasAnyRegions(ISafeAreaView2 sav2)
194194 /// <summary>
195195 /// WindowInsets listener for ContentViewGroup and LayoutViewGroup.
196196 /// </summary>
197- public class WindowInsetsListener ( SafeAreaHandler handler , Action requestLayout ) : Java . Lang . Object , IOnApplyWindowInsetsListener
197+ public class WindowInsetsListener ( SafeAreaHandler handler ) : Java . Lang . Object , IOnApplyWindowInsetsListener
198198 {
199199 readonly WeakReference < SafeAreaHandler > _handlerRef = new ( handler ?? throw new ArgumentNullException ( nameof ( handler ) ) ) ;
200- readonly WeakReference < Action > _requestLayoutRef = new ( requestLayout ?? throw new ArgumentNullException ( nameof ( requestLayout ) ) ) ;
201200
202201 public WindowInsetsCompat OnApplyWindowInsets ( View v , WindowInsetsCompat insets )
203202 {
@@ -208,7 +207,7 @@ public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets)
208207 }
209208
210209 // Get handler and requestLayout from weak references
211- if ( ! _handlerRef . TryGetTarget ( out var handler ) || ! _requestLayoutRef . TryGetTarget ( out var requestLayout ) )
210+ if ( ! _handlerRef . TryGetTarget ( out var handler ) )
212211 {
213212 // Handler or requestLayout has been garbage collected, return insets unchanged
214213 return insets ;
@@ -223,40 +222,35 @@ public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets)
223222
224223 handler . UpdateKeyboardState ( keyboardInsets , isKeyboardShowing ) ;
225224
226- // Request layout if keyboard state changed
227- if ( wasKeyboardShowing != isKeyboardShowing )
228- {
229- requestLayout ( ) ;
230- }
225+ var viewInsets = handler . GetAdjustedSafeAreaInsets ( ) ;
226+ var context = handler . _context ;
231227
232- requestLayout ( ) ;
228+ v . SetPadding ( ( int ) context . ToPixels ( viewInsets . Left ) , ( int ) context . ToPixels ( viewInsets . Top ) , ( int ) context . ToPixels ( viewInsets . Right ) , ( int ) context . ToPixels ( viewInsets . Bottom ) ) ;
233229
234- var crossPlatformLayout = handler . _getCrossPlatformLayout ( ) ;
235230
236- // Use RespondsToSafeArea to check if this view should handle safe area
237- if ( ! handler . RespondsToSafeArea ( ) )
231+ // This is just a quick hack to demonstrate the idea
232+ // in the real implementation you would check each of these insets against the relative SafeAreaRegions
233+ // and just specify which range is consumed or not
234+ if ( viewInsets . Top > 0 || viewInsets . Bottom > 0 || viewInsets . Left > 0 || viewInsets . Right > 0 )
238235 {
239- // For deeper descendants of ScrollView, consume all insets to prevent double-application
240- return ConsumeAllInsets ( insets ) ;
241- }
242236
243- if ( handler . _getCrossPlatformLayout ( ) is ISafeAreaView2 sav2 && HasAnyRegions ( sav2 ) )
244- {
245- return ConsumeAllInsets ( insets ) ;
237+ // This is also somewhat of a hack, AFAICT you need to reset the padding on all children that were previouslly consuming the insets
238+ // There's probably a more efficient way to do this
239+ // One approach here could be for us to just make one global SafeAreaHandler that gets applied to every view
240+ // and then that handler would have a tracking list of views so it could know where to dispatch and reset.
241+ var descendant = v . FindDescendantView < ViewGroup > ( ( view ) => view is ICrossPlatformLayoutBacking && view != v ) ;
242+ descendant ? . DispatchApplyWindowInsets ( WindowInsets . Consumed ) ;
243+
244+ while ( descendant != null )
245+ {
246+ descendant = descendant . FindDescendantView < ViewGroup > ( ( view ) => view is ICrossPlatformLayoutBacking && view != descendant ) ;
247+ descendant ? . DispatchApplyWindowInsets ( WindowInsets . Consumed ) ;
248+ }
249+
250+ return WindowInsetsCompat . Consumed ;
246251 }
247252
248- // This view is not a ScrollView descendant, pass insets through unchanged
249253 return insets ;
250254 }
251-
252- static WindowInsetsCompat ConsumeAllInsets ( WindowInsetsCompat insets )
253- {
254- // Consume all insets to prevent safe area handling for ScrollView descendants
255- return new WindowInsetsCompat . Builder ( insets )
256- . SetInsets ( WindowInsetsCompat . Type . SystemBars ( ) , AndroidX . Core . Graphics . Insets . None )
257- . SetInsets ( WindowInsetsCompat . Type . DisplayCutout ( ) , AndroidX . Core . Graphics . Insets . None )
258- . SetInsets ( WindowInsetsCompat . Type . Ime ( ) , AndroidX . Core . Graphics . Insets . None )
259- . Build ( ) ;
260- }
261255 }
262- }
256+ }
0 commit comments