| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8096d29 commit f8a2053
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ import type { Point, Position } from './view-interfaces'; | |||
| 2 | 2 | import type { GestureTypes, GestureEventData } from '../../gestures'; | |
| 3 | 3 | import { getNativeScriptGlobals } from '../../../globals/global-utils'; | |
| 4 | 4 | import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, AndroidHelper, androidOverflowEdgeProperty, statusBarStyleProperty } from './view-common'; | |
| 5 | + import { OverflowEdgeIgnore, OverflowEdgeNone, parseEdges } from './overflow-edges.android'; | ||
| 5 | 6 | import { directionProperty } from '../../styling/style-properties'; | |
| 6 | 7 | import { layout } from '../../../utils'; | |
| 7 | 8 | import { Trace } from '../../../trace'; | |
@@ -396,22 +397,6 @@ const INSET_CUTOUT_TOP_CONSUMED = 60; | |||
| 396 | 397 | const INSET_CUTOUT_RIGHT_CONSUMED = 64; | |
| 397 | 398 | const INSET_CUTOUT_BOTTOM_CONSUMED = 68; | |
| 398 | 399 | ||
| 399 | - const OverflowEdgeIgnore = -1; | ||
| 400 | - const OverflowEdgeNone: number = 0; | ||
| 401 | - const OverflowEdgeLeft: number = 1 << 1; | ||
| 402 | - const OverflowEdgeTop: number = 1 << 2; | ||
| 403 | - const OverflowEdgeRight: number = 1 << 3; | ||
| 404 | - const OverflowEdgeBottom: number = 1 << 4; | ||
| 405 | - const OverflowEdgeDontApply: number = 1 << 5; | ||
| 406 | - const OverflowEdgeLeftDontConsume: number = 1 << 6; | ||
| 407 | - const OverflowEdgeTopDontConsume: number = 1 << 7; | ||
| 408 | - const OverflowEdgeRightDontConsume: number = 1 << 8; | ||
| 409 | - const OverflowEdgeBottomDontConsume: number = 1 << 9; | ||
| 410 | - const OverflowEdgeAllButLeft: number = 1 << 10; | ||
| 411 | - const OverflowEdgeAllButTop: number = 1 << 11; | ||
| 412 | - const OverflowEdgeAllButRight: number = 1 << 12; | ||
| 413 | - const OverflowEdgeAllButBottom: number = 1 << 13; | ||
| 414 | - | ||
| 415 | 400 | class Inset { | |
| 416 | 401 | private view: DataView; | |
| 417 | 402 | private data: ArrayBuffer; | |
@@ -565,7 +550,14 @@ class Inset { | |||
| 565 | 550 | } | |
| 566 | 551 | ||
| 567 | 552 | toString() { | |
| 568 | - return `Inset: left=${this.left}, top=${this.top}, right=${this.right}, bottom=${this.bottom}, ` + `leftConsumed=${this.leftConsumed}, topConsumed=${this.topConsumed}, ` + `rightConsumed=${this.rightConsumed}, bottomConsumed=${this.bottomConsumed}, ` + `cutoutLeft=${this.cutoutLeft}, cutoutTop=${this.cutoutTop}, cutoutRight=${this.cutoutRight}, cutoutBottom=${this.cutoutBottom}, ` + `cutoutLeftConsumed=${this.cutoutLeftConsumed}, cutoutTopConsumed=${this.cutoutTopConsumed}, ` + `cutoutRightConsumed=${this.cutoutRightConsumed}, cutoutBottomConsumed=${this.cutoutBottomConsumed}`; | ||
| 553 | + return ( | ||
| 554 | + `Inset: left=${this.left}, top=${this.top}, right=${this.right}, bottom=${this.bottom}, imeBottom=${this.imeBottom}, ` + | ||
| 555 | + `leftConsumed=${this.leftConsumed}, topConsumed=${this.topConsumed}, ` + | ||
| 556 | + `rightConsumed=${this.rightConsumed}, bottomConsumed=${this.bottomConsumed}, imeBottomConsumed=${this.imeBottomConsumed}, ` + | ||
| 557 | + `cutoutLeft=${this.cutoutLeft}, cutoutTop=${this.cutoutTop}, cutoutRight=${this.cutoutRight}, cutoutBottom=${this.cutoutBottom}, ` + | ||
| 558 | + `cutoutLeftConsumed=${this.cutoutLeftConsumed}, cutoutTopConsumed=${this.cutoutTopConsumed}, ` + | ||
| 559 | + `cutoutRightConsumed=${this.cutoutRightConsumed}, cutoutBottomConsumed=${this.cutoutBottomConsumed}` | ||
| 560 | + ); | ||
| 569 | 561 | } | |
| 570 | 562 | ||
| 571 | 563 | toJSON() { | |
@@ -574,10 +566,12 @@ class Inset { | |||
| 574 | 566 | top: this.top, | |
| 575 | 567 | right: this.right, | |
| 576 | 568 | bottom: this.bottom, | |
| 569 | + imeBottom: this.imeBottom, | ||
| 577 | 570 | leftConsumed: this.leftConsumed, | |
| 578 | 571 | topConsumed: this.topConsumed, | |
| 579 | 572 | rightConsumed: this.rightConsumed, | |
| 580 | 573 | bottomConsumed: this.bottomConsumed, | |
| 574 | + imeBottomConsumed: this.imeBottomConsumed, | ||
| 581 | 575 | cutoutLeft: this.cutoutLeft, | |
| 582 | 576 | cutoutTop: this.cutoutTop, | |
| 583 | 577 | cutoutRight: this.cutoutRight, | |
@@ -601,7 +595,6 @@ export class View extends ViewCommon { | |||
| 601 | 595 | private layoutChangeListener: android.view.View.OnLayoutChangeListener; | |
| 602 | 596 | private _rootManager: androidx.fragment.app.FragmentManager; | |
| 603 | 597 | private insetListenerIsSet: boolean; | |
| 604 | - private needsInsetListener: boolean; | ||
| 605 | 598 | ||
| 606 | 599 | nativeViewProtected: android.view.View; | |
| 607 | 600 | ||
@@ -640,9 +633,10 @@ export class View extends ViewCommon { | |||
| 640 | 633 | ||
| 641 | 634 | const isInsetEvent = typeof eventNames === 'string' ? eventNames.indexOf(ViewCommon.androidOverflowInsetEvent) !== -1 : false; | |
| 642 | 635 | ||
| 643 | - if (this.insetListenerIsSet && isInsetEvent && this.nativeViewProtected && (this.nativeViewProtected as any).setInsetListener) { | ||
| 644 | - (this.nativeViewProtected as any).setInsetListener(null); | ||
| 645 | - this.insetListenerIsSet = false; | ||
| 636 | + // Same rule as the layout-changed listener above: one subscriber leaving must not | ||
| 637 | + // silence the native listener while others are still subscribed. | ||
| 638 | + if (this.insetListenerIsSet && isInsetEvent && !this.needsInsetListener()) { | ||
| 639 | + this.clearInsetListener(); | ||
| 646 | 640 | } | |
| 647 | 641 | } | |
| 648 | 642 | ||
@@ -670,12 +664,21 @@ export class View extends ViewCommon { | |||
| 670 | 664 | ); | |
| 671 | 665 | this.insetListenerIsSet = true; | |
| 672 | 666 | } | |
| 673 | - this.needsInsetListener = false; | ||
| 674 | - } else { | ||
| 675 | - this.needsInsetListener = true; | ||
| 676 | 667 | } | |
| 677 | 668 | } | |
| 678 | 669 | ||
| 670 | + private clearInsetListener() { | ||
| 671 | + this.insetListenerIsSet = false; | ||
| 672 | + const nativeView = this.nativeViewProtected as any; | ||
| 673 | + if (nativeView?.setInsetListener) { | ||
| 674 | + nativeView.setInsetListener(null); | ||
| 675 | + } | ||
| 676 | + } | ||
| 677 | + | ||
| 678 | + private needsInsetListener() { | ||
| 679 | + return this.hasListeners(ViewCommon.androidOverflowInsetEvent); | ||
| 680 | + } | ||
| 681 | + | ||
| 679 | 682 | public _getChildFragmentManager(): androidx.fragment.app.FragmentManager { | |
| 680 | 683 | return null; | |
| 681 | 684 | } | |
@@ -837,7 +840,7 @@ export class View extends ViewCommon { | |||
| 837 | 840 | this.setOnLayoutChangeListener(); | |
| 838 | 841 | } | |
| 839 | 842 | ||
| 840 | - if (!this.insetListenerIsSet && this.needsInsetListener) { | ||
| 843 | + if (!this.insetListenerIsSet && this.needsInsetListener()) { | ||
| 841 | 844 | this.setInsetListener(); | |
| 842 | 845 | } | |
| 843 | 846 | } | |
@@ -860,6 +863,9 @@ export class View extends ViewCommon { | |||
| 860 | 863 | this.layoutChangeListener = null; | |
| 861 | 864 | } | |
| 862 | 865 | } | |
| 866 | + if (this.insetListenerIsSet) { | ||
| 867 | + this.clearInsetListener(); | ||
| 868 | + } | ||
| 863 | 869 | super.disposeNativeView(); | |
| 864 | 870 | } | |
| 865 | 871 | ||
@@ -1773,36 +1779,6 @@ export class View extends ViewCommon { | |||
| 1773 | 1779 | } | |
| 1774 | 1780 | } | |
| 1775 | 1781 | ||
| 1776 | - const edgeMap: Record<string, number> = { | ||
| 1777 | - none: OverflowEdgeNone, | ||
| 1778 | - left: OverflowEdgeLeft, | ||
| 1779 | - top: OverflowEdgeTop, | ||
| 1780 | - right: OverflowEdgeRight, | ||
| 1781 | - bottom: OverflowEdgeBottom, | ||
| 1782 | - 'dont-apply': OverflowEdgeDontApply, | ||
| 1783 | - 'left-dont-consume': OverflowEdgeLeftDontConsume, | ||
| 1784 | - 'top-dont-consume': OverflowEdgeTopDontConsume, | ||
| 1785 | - 'right-dont-consume': OverflowEdgeRightDontConsume, | ||
| 1786 | - 'bottom-dont-consume': OverflowEdgeBottomDontConsume, | ||
| 1787 | - 'all-but-left': OverflowEdgeAllButLeft, | ||
| 1788 | - 'all-but-top': OverflowEdgeAllButTop, | ||
| 1789 | - 'all-but-right': OverflowEdgeAllButRight, | ||
| 1790 | - 'all-but-bottom': OverflowEdgeAllButBottom, | ||
| 1791 | - }; | ||
| 1792 | - | ||
| 1793 | - function parseEdges(edges: string): number | null { | ||
| 1794 | - let result = 0; | ||
| 1795 | - const values = edges.split(','); | ||
| 1796 | - for (const raw of values) { | ||
| 1797 | - const value = edgeMap[raw.trim()]; | ||
| 1798 | - if (value === undefined) continue; | ||
| 1799 | - // dont-apply overrides everything else | ||
| 1800 | - if (value === OverflowEdgeDontApply) return value; | ||
| 1801 | - result |= value; | ||
| 1802 | - } | ||
| 1803 | - return result === 0 ? null : result; | ||
| 1804 | - } | ||
| 1805 | - | ||
| 1806 | 1782 | export class ContainerView extends View { | |
| 1807 | 1783 | public iosOverflowSafeArea: boolean; | |
| 1808 | 1784 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,48 @@ | |||
| 1 | + import { describe, it, expect } from 'vitest'; | ||
| 2 | + | ||
| 3 | + import { OverflowEdgeAllButTop, OverflowEdgeBottom, OverflowEdgeBottomDontConsume, OverflowEdgeDontApply, OverflowEdgeIgnore, OverflowEdgeLeft, OverflowEdgeNone, OverflowEdgeRight, OverflowEdgeTop, parseEdges } from './overflow-edges.android'; | ||
| 4 | + | ||
| 5 | + describe('parseEdges', () => { | ||
| 6 | + it('maps a single edge to its flag', () => { | ||
| 7 | + expect(parseEdges('top')).toBe(OverflowEdgeTop); | ||
| 8 | + expect(parseEdges('bottom')).toBe(OverflowEdgeBottom); | ||
| 9 | + expect(parseEdges('left')).toBe(OverflowEdgeLeft); | ||
| 10 | + expect(parseEdges('right')).toBe(OverflowEdgeRight); | ||
| 11 | + expect(parseEdges('all-but-top')).toBe(OverflowEdgeAllButTop); | ||
| 12 | + }); | ||
| 13 | + | ||
| 14 | + it('ORs stacked edges together', () => { | ||
| 15 | + expect(parseEdges('top,bottom')).toBe(OverflowEdgeTop | OverflowEdgeBottom); | ||
| 16 | + expect(parseEdges('left,right,bottom-dont-consume')).toBe(OverflowEdgeLeft | OverflowEdgeRight | OverflowEdgeBottomDontConsume); | ||
| 17 | + }); | ||
| 18 | + | ||
| 19 | + it('tolerates whitespace around each entry', () => { | ||
| 20 | + expect(parseEdges(' top , bottom ')).toBe(OverflowEdgeTop | OverflowEdgeBottom); | ||
| 21 | + }); | ||
| 22 | + | ||
| 23 | + it('treats dont-apply and ignore as sentinels rather than flags', () => { | ||
| 24 | + // OR-ing either into a bitmask would corrupt both, so the first one wins outright. | ||
| 25 | + expect(parseEdges('dont-apply')).toBe(OverflowEdgeDontApply); | ||
| 26 | + expect(parseEdges('dont-apply,bottom')).toBe(OverflowEdgeDontApply); | ||
| 27 | + expect(parseEdges('ignore')).toBe(OverflowEdgeIgnore); | ||
| 28 | + expect(parseEdges('ignore,bottom')).toBe(OverflowEdgeIgnore); | ||
| 29 | + expect(parseEdges('bottom,ignore')).toBe(OverflowEdgeIgnore); | ||
| 30 | + }); | ||
| 31 | + | ||
| 32 | + it('returns none for a value that resolves to none, not null', () => { | ||
| 33 | + // null means "leave the view alone"; a real none has to be applied so the view | ||
| 34 | + // gives back any edges it was handling before. | ||
| 35 | + expect(parseEdges('none')).toBe(OverflowEdgeNone); | ||
| 36 | + expect(parseEdges('none,none')).toBe(OverflowEdgeNone); | ||
| 37 | + }); | ||
| 38 | + | ||
| 39 | + it('returns null when nothing in the value is recognized', () => { | ||
| 40 | + expect(parseEdges('')).toBeNull(); | ||
| 41 | + expect(parseEdges('nope')).toBeNull(); | ||
| 42 | + expect(parseEdges('nope,alsonope')).toBeNull(); | ||
| 43 | + }); | ||
| 44 | + | ||
| 45 | + it('ignores unknown entries mixed in with known ones', () => { | ||
| 46 | + expect(parseEdges('nope,top')).toBe(OverflowEdgeTop); | ||
| 47 | + }); | ||
| 48 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,70 @@ | |||
| 1 | + /** | ||
| 2 | + * Internal helper for the `androidOverflowEdge` property. Kept out of index.android.ts | ||
| 3 | + * so the parsing can be unit tested without pulling the whole view stack in. | ||
| 4 | + * | ||
| 5 | + * The values mirror org.nativescript.widgets.LayoutBase. | ||
| 6 | + */ | ||
| 7 | + | ||
| 8 | + export const OverflowEdgeIgnore = -1; | ||
| 9 | + export const OverflowEdgeNone = 0; | ||
| 10 | + export const OverflowEdgeLeft = 1 << 1; | ||
| 11 | + export const OverflowEdgeTop = 1 << 2; | ||
| 12 | + export const OverflowEdgeRight = 1 << 3; | ||
| 13 | + export const OverflowEdgeBottom = 1 << 4; | ||
| 14 | + export const OverflowEdgeDontApply = 1 << 5; | ||
| 15 | + export const OverflowEdgeLeftDontConsume = 1 << 6; | ||
| 16 | + export const OverflowEdgeTopDontConsume = 1 << 7; | ||
| 17 | + export const OverflowEdgeRightDontConsume = 1 << 8; | ||
| 18 | + export const OverflowEdgeBottomDontConsume = 1 << 9; | ||
| 19 | + export const OverflowEdgeAllButLeft = 1 << 10; | ||
| 20 | + export const OverflowEdgeAllButTop = 1 << 11; | ||
| 21 | + export const OverflowEdgeAllButRight = 1 << 12; | ||
| 22 | + export const OverflowEdgeAllButBottom = 1 << 13; | ||
| 23 | + | ||
| 24 | + const edgeMap: Record<string, number> = { | ||
| 25 | + none: OverflowEdgeNone, | ||
| 26 | + ignore: OverflowEdgeIgnore, | ||
| 27 | + left: OverflowEdgeLeft, | ||
| 28 | + top: OverflowEdgeTop, | ||
| 29 | + right: OverflowEdgeRight, | ||
| 30 | + bottom: OverflowEdgeBottom, | ||
| 31 | + 'dont-apply': OverflowEdgeDontApply, | ||
| 32 | + 'left-dont-consume': OverflowEdgeLeftDontConsume, | ||
| 33 | + 'top-dont-consume': OverflowEdgeTopDontConsume, | ||
| 34 | + 'right-dont-consume': OverflowEdgeRightDontConsume, | ||
| 35 | + 'bottom-dont-consume': OverflowEdgeBottomDontConsume, | ||
| 36 | + 'all-but-left': OverflowEdgeAllButLeft, | ||
| 37 | + 'all-but-top': OverflowEdgeAllButTop, | ||
| 38 | + 'all-but-right': OverflowEdgeAllButRight, | ||
| 39 | + 'all-but-bottom': OverflowEdgeAllButBottom, | ||
| 40 | + }; | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * Turns a comma separated `androidOverflowEdge` value into the flags LayoutBase expects. | ||
| 44 | + * Returns null when nothing in the value was recognized, which means "leave the view alone". | ||
| 45 | + */ | ||
| 46 | + export function parseEdges(edges: string): number | null { | ||
| 47 | + let result = 0; | ||
| 48 | + let matched = false; | ||
| 49 | + | ||
| 50 | + for (const raw of edges.split(',')) { | ||
| 51 | + const value = edgeMap[raw.trim()]; | ||
| 52 | + if (value === undefined) { | ||
| 53 | + continue; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + matched = true; | ||
| 57 | + // `dont-apply` and `ignore` are sentinels rather than bit flags, so OR-ing them | ||
| 58 | + // with an edge would corrupt both. The first one wins outright. | ||
| 59 | + if (value === OverflowEdgeDontApply || value === OverflowEdgeIgnore) { | ||
| 60 | + return value; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + result |= value; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + // A value that legitimately resolves to none (0) still has to be applied, otherwise | ||
| 67 | + // setting the property to e.g. 'none,none' would be a silent no-op that strands the | ||
| 68 | + // view on the edges it had before. | ||
| 69 | + return matched ? result : null; | ||
| 70 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,8 +70,6 @@ export class Frame extends FrameBase { | |||
| 70 | 70 | private _containerViewId = -1; | |
| 71 | 71 | private _tearDownPending = false; | |
| 72 | 72 | private _attachedToWindow = false; | |
| 73 | - _defaultOverflowEdge: number; | ||
| 74 | - _defaultOverflowEdgeValue: string; | ||
| 75 | 73 | /** | |
| 76 | 74 | * This property indicates that the view is to be reused as a root view or has been previously disposed. | |
| 77 | 75 | */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -251,6 +251,7 @@ | |||
| 251 | 251 | } | |
| 252 | 252 | ||
| 253 | 253 | export class LayoutBase extends android.view.ViewGroup { | |
| 254 | + public static OverflowEdgeIgnore: number; | ||
| 254 | 255 | public static OverflowEdgeNone: number; | |
| 255 | 256 | public static OverflowEdgeLeft: number; | |
| 256 | 257 | public static OverflowEdgeTop: number; | |
@@ -268,6 +269,9 @@ | |||
| 268 | 269 | constructor(context: android.content.Context); | |
| 269 | 270 | public getOverflowEdge(): number; | |
| 270 | 271 | public setOverflowEdge(value: number): void; | |
| 272 | + public getEdgeInsets(): androidx.core.graphics.Insets; | ||
| 273 | + public getImeInsets(): androidx.core.graphics.Insets; | ||
| 274 | + public setInsetListener(listener: org.nativescript.widgets.LayoutBase.WindowInsetListener): void; | ||
| 271 | 275 | public getPassThroughParent(): boolean; | |
| 272 | 276 | public setPassThroughParent(value: boolean): void; | |
| 273 | 277 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -232,7 +232,10 @@ public void setPadding(int left, int top, int right, int bottom) { | |||
| 232 | 232 | appliedLeft += edgeInsets.left; | |
| 233 | 233 | appliedTop += edgeInsets.top; | |
| 234 | 234 | appliedRight += edgeInsets.right; | |
| 235 | - appliedBottom += edgeInsets.bottom; | ||
| 235 | + // The inset pass applies max(navigation bar, ime) at the bottom, so re-adding only | ||
| 236 | + // edgeInsets.bottom here would drop the keyboard gap on any setPadding() while the | ||
| 237 | + // keyboard is open. | ||
| 238 | + appliedBottom += Math.max(edgeInsets.bottom, imeInsets.bottom); | ||
| 236 | 239 | } | |
| 237 | 240 | super.setPadding(appliedLeft, appliedTop, appliedRight, appliedBottom); | |
| 238 | 241 | } | |
@@ -246,13 +249,43 @@ private int getInset(int offset) { | |||
| 246 | 249 | } | |
| 247 | 250 | ||
| 248 | 251 | private void resetInset() { | |
| 249 | - getInsetBuffer().position(0); | ||
| 250 | - getInsetBuffer().put(EMPTY_INSETS, 0, EMPTY_INSETS.length); | ||
| 252 | + ByteBuffer buffer = getInsetBuffer(); | ||
| 253 | + buffer.position(0); | ||
| 254 | + buffer.put(EMPTY_INSETS, 0, EMPTY_INSETS.length); | ||
| 255 | + buffer.position(0); | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + /** | ||
| 259 | + * Drops the insets this view baked into its padding and restores the padding the | ||
| 260 | + * owner asked for. Used when the view stops taking part in inset distribution, or | ||
| 261 | + * when a pass reports no insets at all. | ||
| 262 | + */ | ||
| 263 | + private void clearEdgeInsets() { | ||
| 264 | + if (edgeInsets == Insets.NONE && imeInsets == Insets.NONE) { | ||
| 265 | + return; | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + edgeInsets = Insets.NONE; | ||
| 269 | + imeInsets = Insets.NONE; | ||
| 270 | + | ||
| 271 | + applyingEdges = true; | ||
| 272 | + setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); | ||
| 273 | + applyingEdges = false; | ||
| 251 | 274 | } | |
| 252 | 275 | ||
| 253 | 276 | public void setOverflowEdge(int value) { | |
| 277 | + int previous = overflowEdge; | ||
| 254 | 278 | overflowEdge = value; | |
| 255 | 279 | ||
| 280 | + if (value == OverflowEdgeIgnore) { | ||
| 281 | + // The listener stays installed but returns insets untouched from here on, so | ||
| 282 | + // nothing would ever give back the padding an earlier pass applied. | ||
| 283 | + if (previous != OverflowEdgeIgnore) { | ||
| 284 | + clearEdgeInsets(); | ||
| 285 | + } | ||
| 286 | + return; | ||
| 287 | + } | ||
| 288 | + | ||
| 256 | 289 | if (windowInsetsListener == null) { | |
| 257 | 290 | windowInsetsListener = new androidx.core.view.OnApplyWindowInsetsListener() { | |
| 258 | 291 | @NonNull | |
@@ -261,21 +294,24 @@ public WindowInsetsCompat onApplyWindowInsets( | |||
| 261 | 294 | @NonNull View v, | |
| 262 | 295 | @NonNull WindowInsetsCompat insets | |
| 263 | 296 | ) { | |
| 264 | - if (insets.isConsumed() || overflowEdge == OverflowEdgeIgnore) { | ||
| 297 | + if (!(v instanceof LayoutBase)) return insets; | ||
| 298 | + LayoutBase base = (LayoutBase) v; | ||
| 299 | + | ||
| 300 | + if (overflowEdge == OverflowEdgeIgnore) { | ||
| 265 | 301 | return insets; | |
| 266 | 302 | } | |
| 267 | 303 | ||
| 268 | - if (!(v instanceof LayoutBase)) return insets; | ||
| 269 | - LayoutBase base = (LayoutBase) v; | ||
| 304 | + if (insets.isConsumed()) { | ||
| 305 | + // An ancestor took everything, so there is nothing left to hand out - | ||
| 306 | + // give back the padding an earlier pass applied here. | ||
| 307 | + base.clearEdgeInsets(); | ||
| 308 | + return insets; | ||
| 309 | + } | ||
| 270 | 310 | ||
| 271 | 311 | Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); | |
| 272 | 312 | Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime()); | |
| 273 | 313 | Insets cutout = insets.getInsets(WindowInsetsCompat.Type.displayCutout()); | |
| 274 | 314 | ||
| 275 | - if (systemBars == Insets.NONE && ime == Insets.NONE) { | ||
| 276 | - return WindowInsetsCompat.CONSUMED; | ||
| 277 | - } | ||
| 278 | - | ||
| 279 | 315 | int insetLeft = systemBars.left; | |
| 280 | 316 | int insetRight = systemBars.right; | |
| 281 | 317 | int insetTop = systemBars.top; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments