Skip to content

Commit 6d89641

Browse files
committed
Add support to apply IME window insets
1 parent 52c7587 commit 6d89641

File tree

1 file changed

+318
-1
lines changed

1 file changed

+318
-1
lines changed

dynamic-utils/src/main/java/com/pranavpandey/android/dynamic/util/DynamicInputUtils.java

Lines changed: 318 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2022 Pranav Pandey
2+
* Copyright 2017-2025 Pranav Pandey
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,9 +18,15 @@
1818

1919
import android.text.InputFilter;
2020
import android.view.View;
21+
import android.view.ViewGroup;
2122
import android.widget.TextView;
2223

24+
import androidx.annotation.NonNull;
2325
import androidx.annotation.Nullable;
26+
import androidx.core.graphics.Insets;
27+
import androidx.core.view.OnApplyWindowInsetsListener;
28+
import androidx.core.view.ViewCompat;
29+
import androidx.core.view.WindowInsetsCompat;
2430

2531
import java.util.ArrayList;
2632
import java.util.Arrays;
@@ -111,4 +117,315 @@ public static void setAllCaps(@Nullable View view, boolean allCaps) {
111117
removeFilter(view, new InputFilter.AllCaps());
112118
}
113119
}
120+
121+
/**
122+
* Apply window insets padding for the supplied view.
123+
*
124+
* @param view The view to set the insets padding.
125+
* @param left {@code true} to apply the left window inset padding.
126+
* @param top {@code true} to apply the top window inset padding.
127+
* @param right {@code true} to apply the right window inset padding.
128+
* @param bottom {@code true} to apply the bottom window inset padding.
129+
* @param consume {@code true} to consume the applied window insets.
130+
*/
131+
public static void applyWindowInsets(@Nullable View view, final boolean left,
132+
final boolean top, final boolean right, final boolean bottom, final boolean consume) {
133+
if (view == null) {
134+
return;
135+
}
136+
137+
final int paddingLeft = view.getPaddingLeft();
138+
final int paddingTop = view.getPaddingTop();
139+
final int paddingRight = view.getPaddingRight();
140+
final int paddingBottom = view.getPaddingBottom();
141+
142+
ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener() {
143+
@Override
144+
public @NonNull WindowInsetsCompat onApplyWindowInsets(
145+
@NonNull View v, @NonNull WindowInsetsCompat insets) {
146+
int insetsLeft = insets.getInsets(WindowInsetsCompat.Type.ime()).left > 0
147+
? insets.getInsets(WindowInsetsCompat.Type.ime()).left
148+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).left;
149+
int insetsTop = insets.getInsets(WindowInsetsCompat.Type.ime()).top > 0
150+
? insets.getInsets(WindowInsetsCompat.Type.ime()).top
151+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
152+
int insetsRight = insets.getInsets(WindowInsetsCompat.Type.ime()).right > 0
153+
? insets.getInsets(WindowInsetsCompat.Type.ime()).right
154+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).right;
155+
int insetsBottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom > 0
156+
? insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
157+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
158+
159+
v.setPadding(left ? paddingLeft + insetsLeft : paddingLeft,
160+
top ? paddingTop + insetsTop : paddingTop,
161+
right ? paddingRight + insetsRight : paddingRight,
162+
bottom ? paddingBottom + insetsBottom : paddingBottom);
163+
164+
return !consume ? insets :
165+
new WindowInsetsCompat.Builder(insets).setInsets(
166+
WindowInsetsCompat.Type.ime(), Insets.of(
167+
left ? 0 : insetsLeft,
168+
top ? 0 : insetsTop,
169+
right ? 0 : insetsRight,
170+
bottom ? 0 : insetsBottom))
171+
.build();
172+
}
173+
});
174+
175+
DynamicViewUtils.requestApplyWindowInsets(view);
176+
}
177+
178+
/**
179+
* Apply horizontal window insets padding for the supplied view.
180+
*
181+
* @param view The view to set the insets padding.
182+
* @param consume {@code true} to consume the applied window insets.
183+
*
184+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
185+
*/
186+
public static void applyWindowInsetsHorizontal(@Nullable View view, boolean consume) {
187+
applyWindowInsets(view, true, false, true, false, consume);
188+
}
189+
190+
/**
191+
* Apply horizontal window insets padding for the supplied view.
192+
*
193+
* @param view The view to set the insets padding.
194+
*
195+
* @see #applyWindowInsetsHorizontal(View, boolean)
196+
*/
197+
public static void applyWindowInsetsHorizontal(@Nullable View view) {
198+
applyWindowInsetsHorizontal(view, false);
199+
}
200+
201+
/**
202+
* Apply vertical window insets padding for the supplied view.
203+
*
204+
* @param view The view to set the insets padding.
205+
* @param consume {@code true} to consume the applied window insets.
206+
*
207+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
208+
*/
209+
public static void applyWindowInsetsVertical(@Nullable View view, boolean consume) {
210+
applyWindowInsets(view, false, true, false, true, consume);
211+
}
212+
213+
/**
214+
* Apply vertical window insets padding for the supplied view.
215+
*
216+
* @param view The view to set the insets padding.
217+
*
218+
* @see #applyWindowInsetsVertical(View, boolean)
219+
*/
220+
public static void applyWindowInsetsVertical(@Nullable View view) {
221+
applyWindowInsetsVertical(view, false);
222+
}
223+
224+
/**
225+
* Apply bottom window insets padding for the supplied view.
226+
*
227+
* @param view The view to set the insets padding.
228+
* @param consume {@code true} to consume the applied window insets.
229+
*
230+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
231+
*/
232+
public static void applyWindowInsetsBottom(@Nullable View view, boolean consume) {
233+
applyWindowInsets(view, false, false, false, true, consume);
234+
}
235+
236+
/**
237+
* Apply bottom window insets padding for the supplied view.
238+
*
239+
* @param view The view to set the insets padding.
240+
*
241+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
242+
*/
243+
public static void applyWindowInsetsBottom(@Nullable View view) {
244+
applyWindowInsetsBottom(view, false);
245+
}
246+
247+
/**
248+
* Apply horizontal and bottom window insets padding for the supplied view.
249+
*
250+
* @param view The view to set the insets padding.
251+
* @param consume {@code true} to consume the applied window insets.
252+
*
253+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
254+
*/
255+
public static void applyWindowInsetsHorizontalBottom(@Nullable View view, boolean consume) {
256+
applyWindowInsets(view, true, false, true, true, consume);
257+
}
258+
259+
/**
260+
* Apply horizontal and bottom window insets padding for the supplied view.
261+
*
262+
* @param view The view to set the insets padding.
263+
*
264+
* @see #applyWindowInsets(View, boolean, boolean, boolean, boolean, boolean)
265+
*/
266+
public static void applyWindowInsetsHorizontalBottom(@Nullable View view) {
267+
applyWindowInsetsHorizontalBottom(view, false);
268+
}
269+
270+
/**
271+
* Apply window insets margin for the supplied view.
272+
*
273+
* @param view The view to set the insets margin.
274+
* @param left {@code true} to apply the left window inset margin.
275+
* @param top {@code true} to apply the top window inset margin.
276+
* @param right {@code true} to apply the right window inset margin.
277+
* @param bottom {@code true} to apply the bottom window inset margin.
278+
* @param consume {@code true} to consume the applied window margin.
279+
*/
280+
public static void applyWindowInsetsMargin(final @Nullable View view, final boolean left,
281+
final boolean top, final boolean right, final boolean bottom, final boolean consume) {
282+
if (view == null || !(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) {
283+
return;
284+
}
285+
286+
final ViewGroup.MarginLayoutParams layoutParams =
287+
(ViewGroup.MarginLayoutParams) view.getLayoutParams();
288+
final int leftMargin = layoutParams.leftMargin;
289+
final int topMargin = layoutParams.topMargin;
290+
final int rightMargin = layoutParams.rightMargin;
291+
final int bottomMargin = layoutParams.bottomMargin;
292+
293+
ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener() {
294+
@Override
295+
public @NonNull WindowInsetsCompat onApplyWindowInsets(
296+
@NonNull View v, @NonNull WindowInsetsCompat insets) {
297+
int insetsLeft = insets.getInsets(WindowInsetsCompat.Type.ime()).left > 0
298+
? insets.getInsets(WindowInsetsCompat.Type.ime()).left
299+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).left;
300+
int insetsTop = insets.getInsets(WindowInsetsCompat.Type.ime()).top > 0
301+
? insets.getInsets(WindowInsetsCompat.Type.ime()).top
302+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
303+
int insetsRight = insets.getInsets(WindowInsetsCompat.Type.ime()).right > 0
304+
? insets.getInsets(WindowInsetsCompat.Type.ime()).right
305+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).right;
306+
int insetsBottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom > 0
307+
? insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
308+
: insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
309+
310+
if (left) {
311+
layoutParams.leftMargin = leftMargin + insetsLeft;
312+
}
313+
if (top) {
314+
layoutParams.topMargin = topMargin + insetsTop;
315+
}
316+
if (right) {
317+
layoutParams.rightMargin = rightMargin + insetsRight;
318+
}
319+
if (bottom) {
320+
layoutParams.bottomMargin = bottomMargin + insetsBottom;
321+
}
322+
323+
view.setLayoutParams(layoutParams);
324+
325+
return !consume ? insets :
326+
new WindowInsetsCompat.Builder(insets).setInsets(
327+
WindowInsetsCompat.Type.systemBars(), Insets.of(
328+
left ? 0 : insetsLeft,
329+
top ? 0 : insetsTop,
330+
right ? 0 : insetsRight,
331+
bottom ? 0 : insetsBottom))
332+
.build();
333+
}
334+
});
335+
336+
DynamicViewUtils.requestApplyWindowInsets(view);
337+
}
338+
339+
/**
340+
* Apply horizontal window insets margin for the supplied view.
341+
*
342+
* @param view The view to set the insets margin.
343+
* @param consume {@code true} to consume the applied window insets.
344+
*
345+
* @see #applyWindowInsetsMargin(View, boolean, boolean, boolean, boolean, boolean)
346+
*/
347+
public static void applyWindowInsetsMarginHorizontal(@Nullable View view, boolean consume) {
348+
applyWindowInsetsMargin(view, true, false, true, false, consume);
349+
}
350+
351+
/**
352+
* Apply horizontal window insets margin for the supplied view.
353+
*
354+
* @param view The view to set the insets margin.
355+
*
356+
* @see #applyWindowInsetsMarginHorizontal(View, boolean)
357+
*/
358+
public static void applyWindowInsetsMarginHorizontal(@Nullable View view) {
359+
applyWindowInsetsMarginHorizontal(view, false);
360+
}
361+
362+
/**
363+
* Apply vertical window insets margin for the supplied view.
364+
*
365+
* @param view The view to set the insets margin.
366+
* @param consume {@code true} to consume the applied window insets.
367+
*
368+
* @see #applyWindowInsetsMargin(View, boolean, boolean, boolean, boolean, boolean)
369+
*/
370+
public static void applyWindowInsetsMarginVertical(@Nullable View view, boolean consume) {
371+
applyWindowInsetsMargin(view, false, true, false, true, consume);
372+
}
373+
374+
/**
375+
* Apply vertical window insets margin for the supplied view.
376+
*
377+
* @param view The view to set the insets margin.
378+
*
379+
* @see #applyWindowInsetsMarginVertical(View, boolean)
380+
*/
381+
public static void applyWindowInsetsMarginVertical(@Nullable View view) {
382+
applyWindowInsetsMarginVertical(view, false);
383+
}
384+
385+
/**
386+
* Apply bottom window insets margin for the supplied view.
387+
*
388+
* @param view The view to set the insets margin.
389+
* @param consume {@code true} to consume the applied window insets.
390+
*
391+
* @see #applyWindowInsetsMargin(View, boolean, boolean, boolean, boolean, boolean)
392+
*/
393+
public static void applyWindowInsetsMarginBottom(@Nullable View view, boolean consume) {
394+
applyWindowInsetsMargin(view, false, false, false, true, consume);
395+
}
396+
397+
/**
398+
* Apply bottom window insets margin for the supplied view.
399+
*
400+
* @param view The view to set the insets margin.
401+
*
402+
* @see #applyWindowInsetsMarginBottom(View, boolean)
403+
*/
404+
public static void applyWindowInsetsMarginBottom(@Nullable View view) {
405+
applyWindowInsetsMarginBottom(view, false);
406+
}
407+
408+
/**
409+
* Apply horizontal and bottom window insets margin for the supplied view.
410+
*
411+
* @param view The view to set the insets margin.
412+
* @param consume {@code true} to consume the applied window insets.
413+
*
414+
* @see #applyWindowInsetsMargin(View, boolean, boolean, boolean, boolean, boolean)
415+
*/
416+
public static void applyWindowInsetsMarginHorizontalBottom(
417+
@Nullable View view, boolean consume) {
418+
applyWindowInsetsMargin(view, true, false, true, true, consume);
419+
}
420+
421+
/**
422+
* Apply horizontal and bottom window insets margin for the supplied view.
423+
*
424+
* @param view The view to set the insets margin.
425+
*
426+
* @see #applyWindowInsetsMarginHorizontalBottom(View, boolean)
427+
*/
428+
public static void applyWindowInsetsMarginHorizontalBottom(@Nullable View view) {
429+
applyWindowInsetsMarginHorizontalBottom(view, false);
430+
}
114431
}

0 commit comments

Comments
 (0)