Skip to content

Commit 1eab75c

Browse files
Enable edge-to-edge handling across activities
1 parent 6642b4a commit 1eab75c

File tree

6 files changed

+125
-21
lines changed

6 files changed

+125
-21
lines changed

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/onboarding/OnboardingActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.d4rk.androidtutorials.java.databinding.ActivityOnboardingBinding;
1818
import com.d4rk.androidtutorials.java.ui.screens.main.MainActivity;
1919
import com.d4rk.androidtutorials.java.ui.screens.startup.StartupViewModel;
20+
import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate;
2021
import com.google.android.material.tabs.TabLayout;
2122
import com.google.android.material.tabs.TabLayoutMediator;
2223
import com.google.android.ump.ConsentInformation;
@@ -39,6 +40,8 @@ protected void onCreate(Bundle savedInstanceState) {
3940
binding = ActivityOnboardingBinding.inflate(getLayoutInflater());
4041
setContentView(binding.getRoot());
4142

43+
EdgeToEdgeDelegate.apply(this, binding.getRoot());
44+
4245
viewModel = new ViewModelProvider(this).get(OnboardingViewModel.class);
4346

4447
// Fallback: show the consent form again if required.

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/startup/StartupActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.d4rk.androidtutorials.java.databinding.ActivityStartupBinding;
1111
import com.d4rk.androidtutorials.java.startup.StartupInitializer;
1212
import com.d4rk.androidtutorials.java.ui.screens.onboarding.OnboardingActivity;
13+
import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate;
1314
import com.google.android.ump.ConsentRequestParameters;
1415

1516
import dagger.hilt.android.AndroidEntryPoint;
@@ -26,6 +27,8 @@ protected void onCreate(Bundle savedInstanceState) {
2627
ActivityStartupBinding binding = ActivityStartupBinding.inflate(getLayoutInflater());
2728
setContentView(binding.getRoot());
2829

30+
EdgeToEdgeDelegate.apply(this, binding.getRoot());
31+
2932
StartupInitializer.schedule(this);
3033

3134
viewModel = new ViewModelProvider(this).get(StartupViewModel.class);

app/src/main/java/com/d4rk/androidtutorials/java/utils/EdgeToEdgeDelegate.java

Lines changed: 113 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,135 @@
22

33
import android.app.Activity;
44
import android.view.View;
5+
import android.view.ViewGroup;
56

7+
import androidx.annotation.NonNull;
68
import androidx.core.graphics.Insets;
79
import androidx.core.view.ViewCompat;
10+
import androidx.core.view.ViewGroupCompat;
811
import androidx.core.view.WindowCompat;
912
import androidx.core.view.WindowInsetsCompat;
1013

14+
import com.d4rk.androidtutorials.java.R;
15+
1116
public 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+
}

app/src/main/res/layout/activity_onboarding.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
android:layout_width="match_parent"
5-
android:layout_height="match_parent"
6-
android:fitsSystemWindows="true">
5+
android:layout_height="match_parent">
76

87
<com.google.android.material.button.MaterialButton
98
android:id="@+id/buttonSkip"

app/src/main/res/layout/activity_startup.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
android:layout_width="match_parent"
5-
android:layout_height="match_parent"
6-
android:fitsSystemWindows="true">
5+
android:layout_height="match_parent">
76

87
<me.zhanghai.android.fastscroll.FastScrollScrollView
98
android:id="@+id/scroll_view"

app/src/main/res/values/ids.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<item name="tag_edge_to_edge_padding" type="id" />
4+
</resources>

0 commit comments

Comments
 (0)