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