22
33import android .app .Activity ;
44import android .view .View ;
5+ import android .view .ViewGroup ;
56
7+ import androidx .annotation .NonNull ;
68import androidx .core .graphics .Insets ;
79import androidx .core .view .ViewCompat ;
10+ import androidx .core .view .ViewGroupCompat ;
811import androidx .core .view .WindowCompat ;
912import androidx .core .view .WindowInsetsCompat ;
1013
14+ import com .d4rk .androidtutorials .java .R ;
15+
1116public final class EdgeToEdgeDelegate {
1217
1318 private EdgeToEdgeDelegate () {
1419 // Utility class
1520 }
1621
17- public static void apply (Activity activity , View container ) {
18- WindowCompat .setDecorFitsSystemWindows (activity .getWindow (), false );
19-
20- ViewCompat .setOnApplyWindowInsetsListener (container , (v , insets ) -> {
21- Insets bars = insets .getInsets (WindowInsetsCompat .Type .systemBars () | WindowInsetsCompat .Type .displayCutout ());
22- v .setPadding (bars .left , bars .top , bars .right , bars .bottom );
23- return WindowInsetsCompat .CONSUMED ;
24- });
22+ public static void apply (Activity activity , View view ) {
23+ enableEdgeToEdge (activity );
24+ applyInsetsAsPadding (
25+ view ,
26+ WindowInsetsCompat .Type .systemBars () | WindowInsetsCompat .Type .displayCutout (),
27+ true ,
28+ true ,
29+ true ,
30+ true
31+ );
2532 }
2633
2734 public static void applyBottomBar (Activity activity , View container , View bottomNavigationView ) {
28- WindowCompat .setDecorFitsSystemWindows (activity .getWindow (), false );
35+ enableEdgeToEdge (activity );
36+ applyInsetsAsPadding (
37+ container ,
38+ WindowInsetsCompat .Type .systemBars () | WindowInsetsCompat .Type .displayCutout (),
39+ true ,
40+ true ,
41+ true ,
42+ false
43+ );
44+ applyInsetsAsPadding (
45+ bottomNavigationView ,
46+ WindowInsetsCompat .Type .systemBars () | WindowInsetsCompat .Type .displayCutout (),
47+ true ,
48+ false ,
49+ true ,
50+ true
51+ );
52+ }
53+
54+ private static void enableEdgeToEdge (Activity activity ) {
55+ if (activity == null ) {
56+ return ;
57+ }
58+ WindowCompat .enableEdgeToEdge (activity .getWindow ());
59+ }
60+
61+ private static void applyInsetsAsPadding (View view , int insetTypes ,
62+ boolean applyStart , boolean applyTop ,
63+ boolean applyEnd , boolean applyBottom ) {
64+ if (view == null ) {
65+ return ;
66+ }
67+
68+ if (view instanceof ViewGroup viewGroup ) {
69+ ViewGroupCompat .installCompatInsetsDispatch (viewGroup );
70+ }
2971
30- ViewCompat .setOnApplyWindowInsetsListener (container , (v , insets ) -> {
31- Insets bars = insets .getInsets (WindowInsetsCompat .Type .systemBars () | WindowInsetsCompat .Type .displayCutout ());
32- v .setPadding (bars .left , bars .top , bars .right , 0 );
72+ InsetsPadding basePadding = (InsetsPadding ) view .getTag (R .id .tag_edge_to_edge_padding );
73+ if (basePadding == null ) {
74+ basePadding = new InsetsPadding (
75+ view .getPaddingStart (),
76+ view .getPaddingTop (),
77+ view .getPaddingEnd (),
78+ view .getPaddingBottom ()
79+ );
80+ view .setTag (R .id .tag_edge_to_edge_padding , basePadding );
81+ }
3382
34- if (bottomNavigationView != null ) {
35- bottomNavigationView .setPadding (0 , 0 , 0 , bars .bottom );
36- }
37- return WindowInsetsCompat .CONSUMED ;
83+ InsetsPadding padding = basePadding ;
84+ ViewCompat .setOnApplyWindowInsetsListener (view , (v , windowInsets ) -> {
85+ Insets insets = windowInsets .getInsets (insetTypes );
86+ int start = applyStart ? insets .left : 0 ;
87+ int top = applyTop ? insets .top : 0 ;
88+ int end = applyEnd ? insets .right : 0 ;
89+ int bottom = applyBottom ? insets .bottom : 0 ;
90+
91+ ViewCompat .setPaddingRelative (
92+ v ,
93+ padding .start + start ,
94+ padding .top + top ,
95+ padding .end + end ,
96+ padding .bottom + bottom
97+ );
98+ return windowInsets ;
3899 });
100+
101+ requestApplyInsetsWhenAttached (view );
102+ }
103+
104+ private static void requestApplyInsetsWhenAttached (@ NonNull View view ) {
105+ if (ViewCompat .isAttachedToWindow (view )) {
106+ ViewCompat .requestApplyInsets (view );
107+ } else {
108+ view .addOnAttachStateChangeListener (new View .OnAttachStateChangeListener () {
109+ @ Override
110+ public void onViewAttachedToWindow (View v ) {
111+ v .removeOnAttachStateChangeListener (this );
112+ ViewCompat .requestApplyInsets (v );
113+ }
114+
115+ @ Override
116+ public void onViewDetachedFromWindow (View v ) {
117+ // No-op
118+ }
119+ });
120+ }
121+ }
122+
123+ private static final class InsetsPadding {
124+ final int start ;
125+ final int top ;
126+ final int end ;
127+ final int bottom ;
128+
129+ InsetsPadding (int start , int top , int end , int bottom ) {
130+ this .start = start ;
131+ this .top = top ;
132+ this .end = end ;
133+ this .bottom = bottom ;
134+ }
39135 }
40- }
136+ }
0 commit comments