@@ -70,10 +70,12 @@ import kotlin.math.abs
7070import kotlin.math.roundToInt
7171
7272/* *
73- * A [TopAppBar] that can collapse and expand based on the scroll position of the content below it.
73+ * A [TopAppBar] with Miuix style that can collapse and expand based on the
74+ * scroll position of the content below it.
7475 *
75- * The [TopAppBar] can be configured with a title, a navigation icon, and action icons. The large
76- * title will collapse when the content is scrolled up and expand when the content is scrolled down.
76+ * The [TopAppBar] can be configured with a title, a navigation icon, and action icons.
77+ * The large title will collapse when the content is scrolled up and expand when
78+ * the content is scrolled down.
7779 *
7880 * @param title The title of the [TopAppBar].
7981 * @param modifier The modifier to be applied to the [TopAppBar].
@@ -83,7 +85,7 @@ import kotlin.math.roundToInt
8385 * @param actions The [Composable] content that represents the action icons.
8486 * @param scrollBehavior The [ScrollBehavior] that controls the behavior of the [TopAppBar].
8587 * @param defaultWindowInsetsPadding Whether to apply default window insets padding to the [TopAppBar].
86- * @param horizontalPadding The horizontal padding of the [TopAppBar].
88+ * @param horizontalPadding The horizontal padding of the [TopAppBar]'s title & large title .
8789 */
8890@Composable
8991fun TopAppBar (
@@ -122,45 +124,42 @@ fun TopAppBar(
122124 )
123125 }
124126
125- val dragConsumerModifier = remember { Modifier .pointerInput(Unit ) { detectVerticalDragGestures { _, _ -> } } }
126-
127- val displayCutoutInsets = WindowInsets .displayCutout
128- val navigationBarsInsets = WindowInsets .navigationBars
129-
130- val windowInsetsModifier = remember(defaultWindowInsetsPadding, displayCutoutInsets, navigationBarsInsets) {
131- if (defaultWindowInsetsPadding) {
132- Modifier
133- .windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides .Horizontal ))
134- .windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides .Horizontal ))
135- } else Modifier
136- }
137- val surfaceModifier = remember(modifier, dragConsumerModifier, windowInsetsModifier) {
138- modifier
139- .then(dragConsumerModifier)
140- .then(windowInsetsModifier)
141- }
142-
143127 // Compose a Surface with a TopAppBarLayout content.
144128 // The surface's background color is animated as specified above.
145129 // The height of the app bar is determined by subtracting the bar's height offset from the
146130 // app bar's defined constant height value (i.e. the ContainerHeight token).
147131 Surface (
148- color = color,
149- modifier = surfaceModifier
132+ color = color
150133 ) {
151134 TopAppBarLayout (
135+ modifier = modifier,
152136 title = title,
153137 largeTitle = largeTitle ? : title,
154138 navigationIcon = navigationIcon,
155139 actions = actionsRow,
156140 scrolledOffset = { scrollBehavior?.state?.heightOffset ? : 0f },
157141 expandedHeightPx = expandedHeightPx,
158142 horizontalPadding = horizontalPadding,
159- largeTitleHeight = largeTitleHeight
143+ largeTitleHeight = largeTitleHeight,
144+ defaultWindowInsetsPadding = defaultWindowInsetsPadding
160145 )
161146 }
162147}
163148
149+ /* *
150+ * A [SmallTopAppBar] with Miuix style.
151+ *
152+ * The [SmallTopAppBar] can be configured with a title, a navigation icon, and action icons.
153+ *
154+ * @param title The title of the [SmallTopAppBar].
155+ * @param modifier The modifier to be applied to the [SmallTopAppBar].
156+ * @param color The background color of the [SmallTopAppBar].
157+ * @param navigationIcon The [Composable] content that represents the navigation icon.
158+ * @param actions The [Composable] content that represents the action icons.
159+ * @param scrollBehavior The [ScrollBehavior] that controls the behavior of the [SmallTopAppBar].
160+ * @param defaultWindowInsetsPadding Whether to apply default window insets padding to the [SmallTopAppBar].
161+ * @param horizontalPadding The horizontal padding of the [SmallTopAppBar]'s title.
162+ */
164163@Composable
165164fun SmallTopAppBar (
166165 title : String ,
@@ -188,37 +187,20 @@ fun SmallTopAppBar(
188187 )
189188 }
190189
191- val dragConsumerModifier = remember { Modifier .pointerInput(Unit ) { detectVerticalDragGestures { _, _ -> } } }
192-
193- val displayCutoutInsets = WindowInsets .displayCutout
194- val navigationBarsInsets = WindowInsets .navigationBars
195-
196- val windowInsetsModifier = remember(defaultWindowInsetsPadding, displayCutoutInsets, navigationBarsInsets) {
197- if (defaultWindowInsetsPadding) {
198- Modifier
199- .windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides .Horizontal ))
200- .windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides .Horizontal ))
201- } else Modifier
202- }
203- val surfaceModifier = remember(modifier, dragConsumerModifier, windowInsetsModifier) {
204- modifier
205- .then(dragConsumerModifier)
206- .then(windowInsetsModifier)
207- }
208-
209190 // Compose a Surface with a SmallTopAppBarLayout content.
210191 // The surface's background color is animated as specified above.
211192 // The height of the app bar is determined by subtracting the bar's height offset from the
212193 // app bar's defined constant height value (i.e. the ContainerHeight token).
213194 Surface (
214- color = color,
215- modifier = surfaceModifier
195+ color = color
216196 ) {
217197 SmallTopAppBarLayout (
198+ modifier = modifier,
218199 title = title,
219200 navigationIcon = navigationIcon,
220201 actions = actionsRow,
221- horizontalPadding = horizontalPadding
202+ horizontalPadding = horizontalPadding,
203+ defaultWindowInsetsPadding = defaultWindowInsetsPadding
222204 )
223205 }
224206}
@@ -557,25 +539,28 @@ private fun interface ScrolledOffset {
557539 * (leading icon), a title (header), and action icons (trailing icons). Note that the navigation and
558540 * the actions are optional.
559541 *
542+ * @param modifier the modifier to be applied to the [TopAppBar].
560543 * @param title the top app bar title (header).
561544 * @param largeTitle the large title of the top app bar, if not specified, it will be the same as title.
562545 * @param navigationIcon a navigation icon [Composable].
563546 * @param actions actions [Composable].
564547 * @param scrolledOffset a function that provides the scroll offset of the top app bar.
565548 * @param expandedHeightPx the expanded height of the top app bar in pixels.
566- * @param horizontalPadding the horizontal padding of the [TopAppBar].
549+ * @param horizontalPadding the horizontal padding of the [TopAppBar]'s title & large title .
567550 * @param largeTitleHeight a mutable state that holds the height of the large title.
568551 */
569552@Composable
570553private fun TopAppBarLayout (
554+ modifier : Modifier = Modifier ,
571555 title : String ,
572556 largeTitle : String ,
573557 navigationIcon : @Composable () -> Unit ,
574558 actions : @Composable () -> Unit ,
575559 scrolledOffset : ScrolledOffset ,
576560 expandedHeightPx : Float ,
577561 horizontalPadding : Dp ,
578- largeTitleHeight : MutableState <Int >
562+ largeTitleHeight : MutableState <Int >,
563+ defaultWindowInsetsPadding : Boolean
579564) {
580565 // Subtract the scrolledOffset from the maxHeight. The scrolledOffset is expected to be
581566 // equal or smaller than zero.
@@ -620,6 +605,24 @@ private fun TopAppBarLayout(
620605 Modifier .offset { IntOffset (0 , heightOffset) }
621606 }
622607
608+ val statusBarsInsets = WindowInsets .statusBars
609+ val captionBarInsets = WindowInsets .captionBar
610+ val displayCutoutInsets = WindowInsets .displayCutout
611+ val navigationBarsInsets = WindowInsets .navigationBars
612+
613+ val layoutModifier = remember(defaultWindowInsetsPadding, statusBarsInsets, captionBarInsets) {
614+ modifier
615+ .windowInsetsPadding(statusBarsInsets.only(WindowInsetsSides .Top ))
616+ .windowInsetsPadding(captionBarInsets.only(WindowInsetsSides .Top ))
617+ .then(
618+ if (defaultWindowInsetsPadding) {
619+ Modifier
620+ .windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides .Horizontal ))
621+ .windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides .Horizontal ))
622+ } else modifier
623+ )
624+ }
625+
623626 Layout (
624627 {
625628 Box (
@@ -663,10 +666,9 @@ private fun TopAppBarLayout(
663666 }
664667 }
665668 },
666- modifier = Modifier
667- .windowInsetsPadding(WindowInsets .statusBars.only(WindowInsetsSides .Top ))
668- .windowInsetsPadding(WindowInsets .captionBar.only(WindowInsetsSides .Top ))
669+ modifier = layoutModifier
669670 .clipToBounds()
671+ .pointerInput(Unit ) { detectVerticalDragGestures { _, _ -> } }
670672 ) { measurables, constraints ->
671673 val navigationIconPlaceable =
672674 measurables
@@ -753,24 +755,46 @@ private fun TopAppBarLayout(
753755 * (leading icon), a title (header), and action icons (trailing icons). Note that the navigation and
754756 * the actions are optional.
755757 *
758+ * @param modifier the modifier to be applied to the [SmallTopAppBar].
756759 * @param title the top app bar title (header).
757760 * @param navigationIcon a navigation icon [Composable].
758761 * @param actions actions [Composable].
759- * @param horizontalPadding the horizontal padding of the [SmallTopAppBar].
762+ * @param horizontalPadding the horizontal padding of the [SmallTopAppBar]'s title.
763+ * @param defaultWindowInsetsPadding whether to apply default window insets padding to the [SmallTopAppBar].
760764 */
761765@Composable
762766private fun SmallTopAppBarLayout (
767+ modifier : Modifier ,
763768 title : String ,
764769 navigationIcon : @Composable () -> Unit ,
765770 actions : @Composable () -> Unit ,
766- horizontalPadding : Dp
771+ horizontalPadding : Dp ,
772+ defaultWindowInsetsPadding : Boolean
767773) {
768774 val titleModifier = remember(horizontalPadding) {
769775 Modifier
770776 .layoutId(" title" )
771777 .padding(horizontal = horizontalPadding)
772778 }
773779
780+ val statusBarsInsets = WindowInsets .statusBars
781+ val captionBarInsets = WindowInsets .captionBar
782+ val displayCutoutInsets = WindowInsets .displayCutout
783+ val navigationBarsInsets = WindowInsets .navigationBars
784+
785+ val layoutModifier = remember(defaultWindowInsetsPadding, statusBarsInsets, captionBarInsets) {
786+ modifier
787+ .windowInsetsPadding(statusBarsInsets.only(WindowInsetsSides .Top ))
788+ .windowInsetsPadding(captionBarInsets.only(WindowInsetsSides .Top ))
789+ .then(
790+ if (defaultWindowInsetsPadding) {
791+ Modifier
792+ .windowInsetsPadding(displayCutoutInsets.only(WindowInsetsSides .Horizontal ))
793+ .windowInsetsPadding(navigationBarsInsets.only(WindowInsetsSides .Horizontal ))
794+ } else modifier
795+ )
796+ }
797+
774798 Layout (
775799 {
776800 Box (
@@ -796,10 +820,9 @@ private fun SmallTopAppBarLayout(
796820 actions()
797821 }
798822 },
799- modifier = Modifier
800- .windowInsetsPadding(WindowInsets .statusBars.only(WindowInsetsSides .Top ))
801- .windowInsetsPadding(WindowInsets .captionBar.only(WindowInsetsSides .Top ))
823+ modifier = layoutModifier
802824 .heightIn(max = 56 .dp)
825+ .pointerInput(Unit ) { detectVerticalDragGestures { _, _ -> } }
803826 ) { measurables, constraints ->
804827 val navigationIconPlaceable =
805828 measurables
0 commit comments