WindowInsetsCompat.java revision 79a141a3eaca2b69ae043c1c6b7a61c7db90d644
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.view;
18
19import android.graphics.Rect;
20import android.os.Build;
21
22/**
23 * Describes a set of insets for window content.
24 *
25 * <p>WindowInsetsCompats are immutable and may be expanded to include more inset types in the
26 * future. To adjust insets, use one of the supplied clone methods to obtain a new
27 * WindowInsetsCompat instance with the adjusted properties.</p>
28 */
29public class WindowInsetsCompat {
30    private interface WindowInsetsCompatImpl {
31        int getSystemWindowInsetLeft(Object insets);
32        int getSystemWindowInsetTop(Object insets);
33        int getSystemWindowInsetRight(Object insets);
34        int getSystemWindowInsetBottom(Object insets);
35        boolean hasSystemWindowInsets(Object insets);
36        boolean hasInsets(Object insets);
37        boolean isConsumed(Object insets);
38        boolean isRound(Object insets);
39        WindowInsetsCompat consumeSystemWindowInsets(Object insets);
40        WindowInsetsCompat replaceSystemWindowInsets(Object insets,
41                int left, int top, int right, int bottom);
42        WindowInsetsCompat replaceSystemWindowInsets(Object insets, Rect systemWindowInsets);
43        int getStableInsetTop(Object insets);
44        int getStableInsetLeft(Object insets);
45        int getStableInsetRight(Object insets);
46        int getStableInsetBottom(Object insets);
47        boolean hasStableInsets(Object insets);
48        WindowInsetsCompat consumeStableInsets(Object insets);
49        Object getSourceWindowInsets(Object src);
50    }
51
52    private static class WindowInsetsCompatBaseImpl implements WindowInsetsCompatImpl {
53        @Override
54        public int getSystemWindowInsetLeft(Object insets) {
55            return 0;
56        }
57
58        @Override
59        public int getSystemWindowInsetTop(Object insets) {
60            return 0;
61        }
62
63        @Override
64        public int getSystemWindowInsetRight(Object insets) {
65            return 0;
66        }
67
68        @Override
69        public int getSystemWindowInsetBottom(Object insets) {
70            return 0;
71        }
72
73        @Override
74        public boolean hasSystemWindowInsets(Object insets) {
75            return false;
76        }
77
78        @Override
79        public boolean hasInsets(Object insets) {
80            return false;
81        }
82
83        @Override
84        public boolean isConsumed(Object insets) {
85            return false;
86        }
87
88        @Override
89        public boolean isRound(Object insets) {
90            return false;
91        }
92
93        @Override
94        public WindowInsetsCompat consumeSystemWindowInsets(Object insets) {
95            return null;
96        }
97
98        @Override
99        public WindowInsetsCompat replaceSystemWindowInsets(Object insets, int left, int top, int right, int bottom) {
100            return null;
101        }
102
103        @Override
104        public WindowInsetsCompat replaceSystemWindowInsets(Object insets, Rect systemWindowInsets) {
105            return null;
106        }
107
108        @Override
109        public int getStableInsetTop(Object insets) {
110            return 0;
111        }
112
113        @Override
114        public int getStableInsetLeft(Object insets) {
115            return 0;
116        }
117
118        @Override
119        public int getStableInsetRight(Object insets) {
120            return 0;
121        }
122
123        @Override
124        public int getStableInsetBottom(Object insets) {
125            return 0;
126        }
127
128        @Override
129        public boolean hasStableInsets(Object insets) {
130            return false;
131        }
132
133        @Override
134        public WindowInsetsCompat consumeStableInsets(Object insets) {
135            return null;
136        }
137
138        @Override
139        public Object getSourceWindowInsets(Object src) {
140            return null;
141        }
142    }
143
144    private static class WindowInsetsCompatApi20Impl extends WindowInsetsCompatBaseImpl {
145        @Override
146        public WindowInsetsCompat consumeSystemWindowInsets(Object insets) {
147            return new WindowInsetsCompat(
148                    WindowInsetsCompatApi20.consumeSystemWindowInsets(insets));
149        }
150
151        @Override
152        public int getSystemWindowInsetBottom(Object insets) {
153            return WindowInsetsCompatApi20.getSystemWindowInsetBottom(insets);
154        }
155
156        @Override
157        public int getSystemWindowInsetLeft(Object insets) {
158            return WindowInsetsCompatApi20.getSystemWindowInsetLeft(insets);
159        }
160
161        @Override
162        public int getSystemWindowInsetRight(Object insets) {
163            return WindowInsetsCompatApi20.getSystemWindowInsetRight(insets);
164        }
165
166        @Override
167        public int getSystemWindowInsetTop(Object insets) {
168            return WindowInsetsCompatApi20.getSystemWindowInsetTop(insets);
169        }
170
171        @Override
172        public boolean hasInsets(Object insets) {
173            return WindowInsetsCompatApi20.hasInsets(insets);
174        }
175
176        @Override
177        public boolean hasSystemWindowInsets(Object insets) {
178            return WindowInsetsCompatApi20.hasSystemWindowInsets(insets);
179        }
180
181        @Override
182        public boolean isRound(Object insets) {
183            return WindowInsetsCompatApi20.isRound(insets);
184        }
185
186        @Override
187        public WindowInsetsCompat replaceSystemWindowInsets(Object insets, int left, int top,
188                int right, int bottom) {
189            return new WindowInsetsCompat(WindowInsetsCompatApi20.replaceSystemWindowInsets(insets,
190                    left, top, right, bottom));
191        }
192
193        @Override
194        public Object getSourceWindowInsets(Object src) {
195            return WindowInsetsCompatApi20.getSourceWindowInsets(src);
196        }
197    }
198
199    private static class WindowInsetsCompatApi21Impl extends WindowInsetsCompatApi20Impl {
200        @Override
201        public WindowInsetsCompat consumeStableInsets(Object insets) {
202            return new WindowInsetsCompat(WindowInsetsCompatApi21.consumeStableInsets(insets));
203        }
204
205        @Override
206        public int getStableInsetBottom(Object insets) {
207            return WindowInsetsCompatApi21.getStableInsetBottom(insets);
208        }
209
210        @Override
211        public int getStableInsetLeft(Object insets) {
212            return WindowInsetsCompatApi21.getStableInsetLeft(insets);
213        }
214
215        @Override
216        public int getStableInsetRight(Object insets) {
217            return WindowInsetsCompatApi21.getStableInsetRight(insets);
218        }
219
220        @Override
221        public int getStableInsetTop(Object insets) {
222            return WindowInsetsCompatApi21.getStableInsetTop(insets);
223        }
224
225        @Override
226        public boolean hasStableInsets(Object insets) {
227            return WindowInsetsCompatApi21.hasStableInsets(insets);
228        }
229
230        @Override
231        public boolean isConsumed(Object insets) {
232            return WindowInsetsCompatApi21.isConsumed(insets);
233        }
234
235        @Override
236        public WindowInsetsCompat replaceSystemWindowInsets(Object insets,
237                Rect systemWindowInsets) {
238            return new WindowInsetsCompat(WindowInsetsCompatApi21.replaceSystemWindowInsets(insets,
239                    systemWindowInsets));
240        }
241    }
242
243    private static final WindowInsetsCompatImpl IMPL;
244    static {
245        final int version = Build.VERSION.SDK_INT;
246        if (version >= 21) {
247            IMPL = new WindowInsetsCompatApi21Impl();
248        } else if (version >= 20) {
249            IMPL = new WindowInsetsCompatApi20Impl();
250        } else {
251            IMPL = new WindowInsetsCompatBaseImpl();
252        }
253    }
254
255    private final Object mInsets;
256
257    private WindowInsetsCompat(Object insets) {
258        mInsets = insets;
259    }
260
261    public WindowInsetsCompat(WindowInsetsCompat src) {
262        mInsets = src == null ? null : IMPL.getSourceWindowInsets(src.mInsets);
263    }
264
265    /**
266     * Returns the left system window inset in pixels.
267     *
268     * <p>The system window inset represents the area of a full-screen window that is
269     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
270     * </p>
271     *
272     * @return The left system window inset
273     */
274    public int getSystemWindowInsetLeft() {
275        return IMPL.getSystemWindowInsetLeft(mInsets);
276    }
277
278    /**
279     * Returns the top system window inset in pixels.
280     *
281     * <p>The system window inset represents the area of a full-screen window that is
282     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
283     * </p>
284     *
285     * @return The top system window inset
286     */
287    public int getSystemWindowInsetTop() {
288        return IMPL.getSystemWindowInsetTop(mInsets);
289    }
290
291    /**
292     * Returns the right system window inset in pixels.
293     *
294     * <p>The system window inset represents the area of a full-screen window that is
295     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
296     * </p>
297     *
298     * @return The right system window inset
299     */
300    public int getSystemWindowInsetRight() {
301        return IMPL.getSystemWindowInsetRight(mInsets);
302    }
303
304    /**
305     * Returns the bottom system window inset in pixels.
306     *
307     * <p>The system window inset represents the area of a full-screen window that is
308     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
309     * </p>
310     *
311     * @return The bottom system window inset
312     */
313    public int getSystemWindowInsetBottom() {
314        return IMPL.getSystemWindowInsetBottom(mInsets);
315    }
316
317    /**
318     * Returns true if this WindowInsets has nonzero system window insets.
319     *
320     * <p>The system window inset represents the area of a full-screen window that is
321     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
322     * </p>
323     *
324     * @return true if any of the system window inset values are nonzero
325     */
326    public boolean hasSystemWindowInsets() {
327        return IMPL.hasSystemWindowInsets(mInsets);
328    }
329
330    /**
331     * Returns true if this WindowInsets has any nonzero insets.
332     *
333     * @return true if any inset values are nonzero
334     */
335    public boolean hasInsets() {
336        return IMPL.hasInsets(mInsets);
337    }
338
339    /**
340     * Check if these insets have been fully consumed.
341     *
342     * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods
343     * have been called such that all insets have been set to zero. This affects propagation of
344     * insets through the view hierarchy; insets that have not been fully consumed will continue
345     * to propagate down to child views.</p>
346     *
347     * <p>The result of this method is equivalent to the return value of
348     * {@link android.view.View#fitSystemWindows(android.graphics.Rect)}.</p>
349     *
350     * @return true if the insets have been fully consumed.
351     */
352    public boolean isConsumed() {
353        return IMPL.isConsumed(mInsets);
354    }
355
356    /**
357     * Returns true if the associated window has a round shape.
358     *
359     * <p>A round window's left, top, right and bottom edges reach all the way to the
360     * associated edges of the window but the corners may not be visible. Views responding
361     * to round insets should take care to not lay out critical elements within the corners
362     * where they may not be accessible.</p>
363     *
364     * @return True if the window is round
365     */
366    public boolean isRound() {
367        return IMPL.isRound(mInsets);
368    }
369
370    /**
371     * Returns a copy of this WindowInsets with the system window insets fully consumed.
372     *
373     * @return A modified copy of this WindowInsets
374     */
375    public WindowInsetsCompat consumeSystemWindowInsets() {
376        return IMPL.consumeSystemWindowInsets(mInsets);
377    }
378
379    /**
380     * Returns a copy of this WindowInsets with selected system window insets replaced
381     * with new values.
382     *
383     * @param left New left inset in pixels
384     * @param top New top inset in pixels
385     * @param right New right inset in pixels
386     * @param bottom New bottom inset in pixels
387     * @return A modified copy of this WindowInsets
388     */
389    public WindowInsetsCompat replaceSystemWindowInsets(int left, int top, int right, int bottom) {
390        return IMPL.replaceSystemWindowInsets(mInsets, left, top, right, bottom);
391    }
392
393    /**
394     * Returns a copy of this WindowInsets with selected system window insets replaced
395     * with new values.
396     *
397     * @param systemWindowInsets New system window insets. Each field is the inset in pixels
398     *                           for that edge
399     * @return A modified copy of this WindowInsets
400     */
401    public WindowInsetsCompat replaceSystemWindowInsets(Rect systemWindowInsets) {
402        return IMPL.replaceSystemWindowInsets(mInsets, systemWindowInsets);
403    }
404
405    /**
406     * Returns the top stable inset in pixels.
407     *
408     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
409     * partially or fully obscured by the system UI elements.  This value does not change
410     * based on the visibility state of those elements; for example, if the status bar is
411     * normally shown, but temporarily hidden, the stable inset will still provide the inset
412     * associated with the status bar being shown.</p>
413     *
414     * @return The top stable inset
415     */
416    public int getStableInsetTop() {
417        return IMPL.getStableInsetTop(mInsets);
418    }
419
420
421    /**
422     * Returns the left stable inset in pixels.
423     *
424     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
425     * partially or fully obscured by the system UI elements.  This value does not change
426     * based on the visibility state of those elements; for example, if the status bar is
427     * normally shown, but temporarily hidden, the stable inset will still provide the inset
428     * associated with the status bar being shown.</p>
429     *
430     * @return The left stable inset
431     */
432    public int getStableInsetLeft() {
433        return IMPL.getStableInsetLeft(mInsets);
434    }
435
436    /**
437     * Returns the right stable inset in pixels.
438     *
439     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
440     * partially or fully obscured by the system UI elements.  This value does not change
441     * based on the visibility state of those elements; for example, if the status bar is
442     * normally shown, but temporarily hidden, the stable inset will still provide the inset
443     * associated with the status bar being shown.</p>
444     *
445     * @return The right stable inset
446     */
447    public int getStableInsetRight() {
448        return IMPL.getStableInsetRight(mInsets);
449    }
450
451
452    /**
453     * Returns the bottom stable inset in pixels.
454     *
455     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
456     * partially or fully obscured by the system UI elements.  This value does not change
457     * based on the visibility state of those elements; for example, if the status bar is
458     * normally shown, but temporarily hidden, the stable inset will still provide the inset
459     * associated with the status bar being shown.</p>
460     *
461     * @return The bottom stable inset
462     */
463    public int getStableInsetBottom() {
464        return IMPL.getStableInsetBottom(mInsets);
465    }
466
467    /**
468     * Returns true if this WindowInsets has nonzero stable insets.
469     *
470     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
471     * partially or fully obscured by the system UI elements.  This value does not change
472     * based on the visibility state of those elements; for example, if the status bar is
473     * normally shown, but temporarily hidden, the stable inset will still provide the inset
474     * associated with the status bar being shown.</p>
475     *
476     * @return true if any of the stable inset values are nonzero
477     */
478    public boolean hasStableInsets() {
479        return IMPL.hasStableInsets(mInsets);
480    }
481
482    /**
483     * Returns a copy of this WindowInsets with the stable insets fully consumed.
484     *
485     * @return A modified copy of this WindowInsetsCompat
486     */
487    public WindowInsetsCompat consumeStableInsets() {
488        return IMPL.consumeStableInsets(mInsets);
489    }
490
491    @Override
492    public boolean equals(Object o) {
493        if (this == o) {
494            return true;
495        }
496        if (o == null || getClass() != o.getClass()) {
497            return false;
498        }
499        WindowInsetsCompat other = (WindowInsetsCompat) o;
500        return mInsets == null ? other.mInsets == null : mInsets.equals(other.mInsets);
501    }
502
503    @Override
504    public int hashCode() {
505        return mInsets == null ? 0 : mInsets.hashCode();
506    }
507
508    static WindowInsetsCompat wrap(Object insets) {
509        return insets == null ? null : new WindowInsetsCompat(insets);
510    }
511
512    static Object unwrap(WindowInsetsCompat insets) {
513        return insets == null ? null : insets.mInsets;
514    }
515}
516