WindowInsetsCompat.java revision d739b48735e949e61654bd216e0dddebcb028287
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 /** 262 * Constructs a new WindowInsetsCompat, copying all values from a source WindowInsetsCompat. 263 * 264 * @param src source from which values are copied 265 */ 266 public WindowInsetsCompat(WindowInsetsCompat src) { 267 mInsets = src == null ? null : IMPL.getSourceWindowInsets(src.mInsets); 268 } 269 270 /** 271 * Returns the left system window inset in pixels. 272 * 273 * <p>The system window inset represents the area of a full-screen window that is 274 * partially or fully obscured by the status bar, navigation bar, IME or other system windows. 275 * </p> 276 * 277 * @return The left system window inset 278 */ 279 public int getSystemWindowInsetLeft() { 280 return IMPL.getSystemWindowInsetLeft(mInsets); 281 } 282 283 /** 284 * Returns the top system window inset in pixels. 285 * 286 * <p>The system window inset represents the area of a full-screen window that is 287 * partially or fully obscured by the status bar, navigation bar, IME or other system windows. 288 * </p> 289 * 290 * @return The top system window inset 291 */ 292 public int getSystemWindowInsetTop() { 293 return IMPL.getSystemWindowInsetTop(mInsets); 294 } 295 296 /** 297 * Returns the right system window inset in pixels. 298 * 299 * <p>The system window inset represents the area of a full-screen window that is 300 * partially or fully obscured by the status bar, navigation bar, IME or other system windows. 301 * </p> 302 * 303 * @return The right system window inset 304 */ 305 public int getSystemWindowInsetRight() { 306 return IMPL.getSystemWindowInsetRight(mInsets); 307 } 308 309 /** 310 * Returns the bottom system window inset in pixels. 311 * 312 * <p>The system window inset represents the area of a full-screen window that is 313 * partially or fully obscured by the status bar, navigation bar, IME or other system windows. 314 * </p> 315 * 316 * @return The bottom system window inset 317 */ 318 public int getSystemWindowInsetBottom() { 319 return IMPL.getSystemWindowInsetBottom(mInsets); 320 } 321 322 /** 323 * Returns true if this WindowInsets has nonzero system window insets. 324 * 325 * <p>The system window inset represents the area of a full-screen window that is 326 * partially or fully obscured by the status bar, navigation bar, IME or other system windows. 327 * </p> 328 * 329 * @return true if any of the system window inset values are nonzero 330 */ 331 public boolean hasSystemWindowInsets() { 332 return IMPL.hasSystemWindowInsets(mInsets); 333 } 334 335 /** 336 * Returns true if this WindowInsets has any nonzero insets. 337 * 338 * @return true if any inset values are nonzero 339 */ 340 public boolean hasInsets() { 341 return IMPL.hasInsets(mInsets); 342 } 343 344 /** 345 * Check if these insets have been fully consumed. 346 * 347 * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods 348 * have been called such that all insets have been set to zero. This affects propagation of 349 * insets through the view hierarchy; insets that have not been fully consumed will continue 350 * to propagate down to child views.</p> 351 * 352 * <p>The result of this method is equivalent to the return value of 353 * {@link android.view.View#fitSystemWindows(android.graphics.Rect)}.</p> 354 * 355 * @return true if the insets have been fully consumed. 356 */ 357 public boolean isConsumed() { 358 return IMPL.isConsumed(mInsets); 359 } 360 361 /** 362 * Returns true if the associated window has a round shape. 363 * 364 * <p>A round window's left, top, right and bottom edges reach all the way to the 365 * associated edges of the window but the corners may not be visible. Views responding 366 * to round insets should take care to not lay out critical elements within the corners 367 * where they may not be accessible.</p> 368 * 369 * @return True if the window is round 370 */ 371 public boolean isRound() { 372 return IMPL.isRound(mInsets); 373 } 374 375 /** 376 * Returns a copy of this WindowInsets with the system window insets fully consumed. 377 * 378 * @return A modified copy of this WindowInsets 379 */ 380 public WindowInsetsCompat consumeSystemWindowInsets() { 381 return IMPL.consumeSystemWindowInsets(mInsets); 382 } 383 384 /** 385 * Returns a copy of this WindowInsets with selected system window insets replaced 386 * with new values. 387 * 388 * @param left New left inset in pixels 389 * @param top New top inset in pixels 390 * @param right New right inset in pixels 391 * @param bottom New bottom inset in pixels 392 * @return A modified copy of this WindowInsets 393 */ 394 public WindowInsetsCompat replaceSystemWindowInsets(int left, int top, int right, int bottom) { 395 return IMPL.replaceSystemWindowInsets(mInsets, left, top, right, bottom); 396 } 397 398 /** 399 * Returns a copy of this WindowInsets with selected system window insets replaced 400 * with new values. 401 * 402 * @param systemWindowInsets New system window insets. Each field is the inset in pixels 403 * for that edge 404 * @return A modified copy of this WindowInsets 405 */ 406 public WindowInsetsCompat replaceSystemWindowInsets(Rect systemWindowInsets) { 407 return IMPL.replaceSystemWindowInsets(mInsets, systemWindowInsets); 408 } 409 410 /** 411 * Returns the top stable inset in pixels. 412 * 413 * <p>The stable inset represents the area of a full-screen window that <b>may</b> be 414 * partially or fully obscured by the system UI elements. This value does not change 415 * based on the visibility state of those elements; for example, if the status bar is 416 * normally shown, but temporarily hidden, the stable inset will still provide the inset 417 * associated with the status bar being shown.</p> 418 * 419 * @return The top stable inset 420 */ 421 public int getStableInsetTop() { 422 return IMPL.getStableInsetTop(mInsets); 423 } 424 425 426 /** 427 * Returns the left stable inset in pixels. 428 * 429 * <p>The stable inset represents the area of a full-screen window that <b>may</b> be 430 * partially or fully obscured by the system UI elements. This value does not change 431 * based on the visibility state of those elements; for example, if the status bar is 432 * normally shown, but temporarily hidden, the stable inset will still provide the inset 433 * associated with the status bar being shown.</p> 434 * 435 * @return The left stable inset 436 */ 437 public int getStableInsetLeft() { 438 return IMPL.getStableInsetLeft(mInsets); 439 } 440 441 /** 442 * Returns the right stable inset in pixels. 443 * 444 * <p>The stable inset represents the area of a full-screen window that <b>may</b> be 445 * partially or fully obscured by the system UI elements. This value does not change 446 * based on the visibility state of those elements; for example, if the status bar is 447 * normally shown, but temporarily hidden, the stable inset will still provide the inset 448 * associated with the status bar being shown.</p> 449 * 450 * @return The right stable inset 451 */ 452 public int getStableInsetRight() { 453 return IMPL.getStableInsetRight(mInsets); 454 } 455 456 457 /** 458 * Returns the bottom stable inset in pixels. 459 * 460 * <p>The stable inset represents the area of a full-screen window that <b>may</b> be 461 * partially or fully obscured by the system UI elements. This value does not change 462 * based on the visibility state of those elements; for example, if the status bar is 463 * normally shown, but temporarily hidden, the stable inset will still provide the inset 464 * associated with the status bar being shown.</p> 465 * 466 * @return The bottom stable inset 467 */ 468 public int getStableInsetBottom() { 469 return IMPL.getStableInsetBottom(mInsets); 470 } 471 472 /** 473 * Returns true if this WindowInsets has nonzero stable insets. 474 * 475 * <p>The stable inset represents the area of a full-screen window that <b>may</b> be 476 * partially or fully obscured by the system UI elements. This value does not change 477 * based on the visibility state of those elements; for example, if the status bar is 478 * normally shown, but temporarily hidden, the stable inset will still provide the inset 479 * associated with the status bar being shown.</p> 480 * 481 * @return true if any of the stable inset values are nonzero 482 */ 483 public boolean hasStableInsets() { 484 return IMPL.hasStableInsets(mInsets); 485 } 486 487 /** 488 * Returns a copy of this WindowInsets with the stable insets fully consumed. 489 * 490 * @return A modified copy of this WindowInsetsCompat 491 */ 492 public WindowInsetsCompat consumeStableInsets() { 493 return IMPL.consumeStableInsets(mInsets); 494 } 495 496 @Override 497 public boolean equals(Object o) { 498 if (this == o) { 499 return true; 500 } 501 if (o == null || getClass() != o.getClass()) { 502 return false; 503 } 504 WindowInsetsCompat other = (WindowInsetsCompat) o; 505 return mInsets == null ? other.mInsets == null : mInsets.equals(other.mInsets); 506 } 507 508 @Override 509 public int hashCode() { 510 return mInsets == null ? 0 : mInsets.hashCode(); 511 } 512 513 static WindowInsetsCompat wrap(Object insets) { 514 return insets == null ? null : new WindowInsetsCompat(insets); 515 } 516 517 static Object unwrap(WindowInsetsCompat insets) { 518 return insets == null ? null : insets.mInsets; 519 } 520} 521