refactor: decoupling function classes to scope and impl in ActionBar, Tab

This commit is contained in:
2023-12-02 23:23:14 +08:00
parent 123ee05fe2
commit 5b1ef1bc7e
2 changed files with 53 additions and 40 deletions

View File

@@ -81,7 +81,7 @@ fun TopActionBar(
style: ActionBarStyle? = null, style: ActionBarStyle? = null,
titleText: @Composable () -> Unit, titleText: @Composable () -> Unit,
subText: @Composable (() -> Unit)? = null, subText: @Composable (() -> Unit)? = null,
actions: @Composable (BasicActionBar.() -> Unit)? = null actions: @Composable (ActionBarScope.() -> Unit)? = null
) { ) {
BasicActionBar( BasicActionBar(
type = ActionBarType.LARGE, type = ActionBarType.LARGE,
@@ -103,9 +103,9 @@ fun ActionBar(
style: ActionBarStyle? = null, style: ActionBarStyle? = null,
titleText: @Composable () -> Unit, titleText: @Composable () -> Unit,
subText: @Composable (() -> Unit)? = null, subText: @Composable (() -> Unit)? = null,
finishIcon: @Composable (BasicActionBar.() -> Unit)? = null, finishIcon: @Composable (ActionBarScope.() -> Unit)? = null,
navigationIcon: @Composable (BasicActionBar.() -> Unit)? = null, navigationIcon: @Composable (ActionBarScope.() -> Unit)? = null,
actions: @Composable (BasicActionBar.() -> Unit)? = null actions: @Composable (ActionBarScope.() -> Unit)? = null
) { ) {
BasicActionBar( BasicActionBar(
type = ActionBarType.MIDDLE, type = ActionBarType.MIDDLE,
@@ -128,15 +128,15 @@ private fun BasicActionBar(
style: ActionBarStyle?, style: ActionBarStyle?,
titleText: @Composable () -> Unit, titleText: @Composable () -> Unit,
subText: @Composable (() -> Unit)?, subText: @Composable (() -> Unit)?,
finishIcon: @Composable (BasicActionBar.() -> Unit)?, finishIcon: @Composable (ActionBarScope.() -> Unit)?,
navigationIcon: @Composable (BasicActionBar.() -> Unit)?, navigationIcon: @Composable (ActionBarScope.() -> Unit)?,
actions: @Composable (BasicActionBar.() -> Unit)? actions: @Composable (ActionBarScope.() -> Unit)?
) { ) {
CompositionLocalProvider(LocalActionBarType provides type) { CompositionLocalProvider(LocalActionBarType provides type) {
val currentColors = colors ?: ActionBar.colors val currentColors = colors ?: ActionBar.colors
val currentStyle = style ?: ActionBar.style val currentStyle = style ?: ActionBar.style
Box(modifier = modifier.padding(currentStyle.padding)) { Box(modifier = modifier.padding(currentStyle.padding)) {
BasicActionBar( ActionBarImpl(
type = type, type = type,
colors = currentColors, colors = currentColors,
style = currentStyle, style = currentStyle,
@@ -150,17 +150,8 @@ private fun BasicActionBar(
} }
} }
@Immutable @Stable
class BasicActionBar internal constructor( interface ActionBarScope {
private val type: ActionBarType,
private val colors: ActionBarColors,
private val style: ActionBarStyle,
private val titleText: @Composable () -> Unit,
private val subText: @Composable (() -> Unit)?,
private val finishIcon: @Composable (BasicActionBar.() -> Unit)?,
private val navigationIcon: @Composable (BasicActionBar.() -> Unit)?,
private val actions: @Composable (BasicActionBar.() -> Unit)?
) {
@Composable @Composable
fun FinishIconButton( fun FinishIconButton(
@@ -210,7 +201,7 @@ class BasicActionBar internal constructor(
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val iconInflateSize = this.style.actionIconSize + this.style.actionIconPadding val iconInflateSize = impl.style.actionIconSize + impl.style.actionIconPadding
IconButton( IconButton(
onClick = onClick, onClick = onClick,
modifier = Modifier.size(iconInflateSize).then(modifier), modifier = Modifier.size(iconInflateSize).then(modifier),
@@ -221,9 +212,22 @@ class BasicActionBar internal constructor(
content = content content = content
) )
} }
}
@Immutable
private class ActionBarImpl(
val type: ActionBarType,
val colors: ActionBarColors,
val style: ActionBarStyle,
val titleText: @Composable () -> Unit,
val subText: @Composable (() -> Unit)?,
val finishIcon: @Composable (ActionBarScope.() -> Unit)?,
val navigationIcon: @Composable (ActionBarScope.() -> Unit)?,
val actions: @Composable (ActionBarScope.() -> Unit)?
) : ActionBarScope {
@Composable @Composable
internal fun Content() { fun Content() {
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
val contentMaxWidth = maxWidth val contentMaxWidth = maxWidth
Row( Row(
@@ -308,7 +312,10 @@ class BasicActionBar internal constructor(
} }
@Stable @Stable
internal enum class ActionBarType { LARGE, MIDDLE } private val ActionBarScope.impl get() = this as? ActionBarImpl? ?: error("Could not got ActionBarScope's impl.")
@Stable
private enum class ActionBarType { LARGE, MIDDLE }
object ActionBar { object ActionBar {
val colors: ActionBarColors val colors: ActionBarColors

View File

@@ -102,7 +102,7 @@ fun TabRow(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
colors: TabColors = Tab.colors, colors: TabColors = Tab.colors,
style: TabStyle = Tab.style, style: TabStyle = Tab.style,
indicator: @Composable TabRow.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) }, indicator: @Composable TabRowScope.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) },
tabs: @Composable () -> Unit tabs: @Composable () -> Unit
) { ) {
TabStyleBox(modifier, colors, style) { TabStyleBox(modifier, colors, style) {
@@ -127,7 +127,7 @@ fun TabRow(
placeable.placeRelative(x = index * tabAverageWidth, y = 0) placeable.placeRelative(x = index * tabAverageWidth, y = 0)
} }
subcompose(TabSlots.Indicator) { subcompose(TabSlots.Indicator) {
indicator(TabRow(selectedTabIndex, colors, style, tabPositions)) indicator(TabRowImpl(selectedTabIndex, colors, style, tabPositions))
}.forEach { }.forEach {
it.measure(Constraints.fixed(tabRowWidth, tabRowHeight)).placeRelative(x = 0, y = 0) it.measure(Constraints.fixed(tabRowWidth, tabRowHeight)).placeRelative(x = 0, y = 0)
} }
@@ -143,7 +143,7 @@ fun ScrollableTabRow(
colors: TabColors = Tab.colors, colors: TabColors = Tab.colors,
style: TabStyle = Tab.style, style: TabStyle = Tab.style,
scrollState: ScrollState = rememberScrollState(), scrollState: ScrollState = rememberScrollState(),
indicator: @Composable TabRow.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) }, indicator: @Composable TabRowScope.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) },
tabs: @Composable () -> Unit tabs: @Composable () -> Unit
) { ) {
TabStyleBox(modifier, colors, style) { TabStyleBox(modifier, colors, style) {
@@ -176,7 +176,7 @@ fun ScrollableTabRow(
tabLeft += placeables.width tabLeft += placeables.width
} }
subcompose(TabSlots.Indicator) { subcompose(TabSlots.Indicator) {
indicator(TabRow(selectedTabIndex, colors, style, tabPositions)) indicator(TabRowImpl(selectedTabIndex, colors, style, tabPositions))
}.forEach { }.forEach {
it.measure(Constraints.fixed(layoutWidth, layoutHeight)).placeRelative(x = 0, y = 0) it.measure(Constraints.fixed(layoutWidth, layoutHeight)).placeRelative(x = 0, y = 0)
} }
@@ -265,27 +265,22 @@ data class TabPosition(val left: Dp, val width: Dp, val tabWidth: Dp) {
fun calculateCenter(currentWidth: Dp) = left + width / 2 - currentWidth / 2 fun calculateCenter(currentWidth: Dp) = left + width / 2 - currentWidth / 2
} }
@Immutable @Stable
class TabRow internal constructor( interface TabRowScope {
val selectedTabIndex: Int,
val colors: TabColors,
val style: TabStyle,
val tabPositions: List<TabPosition>
) {
@Composable @Composable
fun TabIndicator( fun TabIndicator(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
color: Color = colors.indicatorColor, color: Color = impl.colors.indicatorColor,
height: Dp = style.indicatorHeight, height: Dp = impl.style.indicatorHeight,
shape: Shape = style.indicatorShape shape: Shape = impl.style.indicatorShape
) { ) {
Box(modifier.height(height).background(color, shape)) Box(modifier.height(height).background(color, shape))
} }
fun Modifier.tabIndicatorOffset( fun Modifier.tabIndicatorOffset(
currentTabPosition: TabPosition = tabPositions[selectedTabIndex], currentTabPosition: TabPosition = impl.tabPositions[impl.selectedTabIndex],
indicatorWidth: Dp = style.indicatorWidth indicatorWidth: Dp = impl.style.indicatorWidth
) = composed( ) = composed(
inspectorInfo = debugInspectorInfo { inspectorInfo = debugInspectorInfo {
name = "tabIndicatorOffset" name = "tabIndicatorOffset"
@@ -310,8 +305,8 @@ class TabRow internal constructor(
fun Modifier.pagerTabIndicatorOffset( fun Modifier.pagerTabIndicatorOffset(
pagerState: PagerState, pagerState: PagerState,
tabPositions: List<TabPosition> = this@TabRow.tabPositions, tabPositions: List<TabPosition> = impl.tabPositions,
indicatorWidth: Dp = style.indicatorWidth indicatorWidth: Dp = impl.style.indicatorWidth
) = composed( ) = composed(
inspectorInfo = debugInspectorInfo { inspectorInfo = debugInspectorInfo {
name = "pagerTabIndicatorOffset" name = "pagerTabIndicatorOffset"
@@ -361,6 +356,17 @@ class TabRow internal constructor(
} }
} }
@Immutable
private class TabRowImpl(
val selectedTabIndex: Int,
val colors: TabColors,
val style: TabStyle,
val tabPositions: List<TabPosition>
) : TabRowScope
@Stable
private val TabRowScope.impl get() = this as? TabRowImpl? ?: error("Could not got TabRowScope's impl.")
@Immutable @Immutable
private class ScrollableTabData(private val scrollState: ScrollState, private val coroutineScope: CoroutineScope) { private class ScrollableTabData(private val scrollState: ScrollState, private val coroutineScope: CoroutineScope) {