Skip to content

Commit

Permalink
fix text field layout
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny-chung committed Jan 15, 2025
1 parent 60bd581 commit d528561
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ package com.sunnychung.application.multiplatform.hellohttp.ux

import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
Expand All @@ -17,7 +14,6 @@ import androidx.compose.material.TextFieldDefaults.indicatorLine
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
Expand Down Expand Up @@ -82,16 +78,12 @@ fun AppTextField(
) {
val textState by rememberConcurrentLargeAnnotatedBigTextFieldState(value, key)

Row(
verticalAlignment = Alignment.CenterVertically,
BigTextFieldLayout(
modifier = modifier
.background(colors.backgroundColor(enabled).value)
.debugConstraints("$key tf row")
) {
if (leadingIcon != null) {
leadingIcon()
}
Box(modifier = Modifier.padding(contentPadding).debugConstraints("$key tf box"), contentAlignment = Alignment.CenterStart) {
.padding(contentPadding)
.debugConstraints("$key tf layout"),
textField = {
CoreBigTextField(
text = textState.text,
viewState = textState.viewState,
Expand All @@ -109,17 +101,63 @@ fun AppTextField(
textTransformation = transformation,
textDecorator = decorator,
isSingleLineInput = singleLine,
// modifier = modifier
modifier = Modifier.fillMaxWidth()
modifier = Modifier
.debugConstraints("$key tf core")
.onGloballyPositioned { log.w { "[$key] tf size = ${it.size}" } }
)

},
leadingIcon = {
leadingIcon?.invoke()
},
placeholder = {
if (placeholder != null && textState.text.isEmpty) {
placeholder()
}
}
}
},
)

// Row(
// verticalAlignment = Alignment.CenterVertically,
// modifier = modifier
// .background(colors.backgroundColor(enabled).value)
// .debugConstraints("$key tf row")
// .height(IntrinsicSize.Min),
// ) {
// if (leadingIcon != null) {
// leadingIcon()
// }
// Box(modifier = Modifier.weight(1f)/*.width(IntrinsicSize.Min).height(IntrinsicSize.Min)*/.padding(contentPadding).debugConstraints("$key tf box"), contentAlignment = Alignment.CenterStart, propagateMinConstraints = true) {
// CoreBigTextField(
// text = textState.text,
// viewState = textState.viewState,
// onTextChange = {
// val newStringValue = it.bigText.buildString()
// log.w { "onTextChange: new = $newStringValue" }
//// onValueChange(newStringValue)
// },
// isEditable = enabled && !readOnly,
// isSelectable = enabled,
// fontSize = textStyle.fontSize,
// fontFamily = textStyle.fontFamily ?: FontFamily.SansSerif,
// color = colors.textColor(enabled).value,
// cursorColor = colors.cursorColor(false).value,
// textTransformation = transformation,
// textDecorator = decorator,
// isSingleLineInput = singleLine,
//// modifier = modifier
// modifier = Modifier //.fillMaxWidth()
//// .fillMaxSize()
//// .wrapContentSize()
// .useMaxSizeOfParentAndChild()
// .debugConstraints("$key tf core")
// .onGloballyPositioned { log.w { "[$key] tf size = ${it.size}" } }
// )
//
// if (placeholder != null && textState.text.isEmpty) {
// placeholder()
// }
// }
// }

return

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.sunnychung.application.multiplatform.hellohttp.ux

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints

@Composable
fun BigTextFieldLayout(
modifier: Modifier = Modifier,
textField: @Composable () -> Unit,
leadingIcon: @Composable () -> Unit = {},
placeholder: @Composable () -> Unit = {},
) {
var index = 0
val TextFieldId = index++
val LeadingId = index++
val PlaceholderId = index++
val contents = MutableList<@Composable () -> Unit>(index) { {} }
contents[TextFieldId] = textField
contents[LeadingId] = leadingIcon
contents[PlaceholderId] = placeholder
Layout(
modifier = modifier,
content = {
contents.forEach {
Box(propagateMinConstraints = true) {
it()
}
}
},
measurePolicy = object : MeasurePolicy {
override fun MeasureScope.measure(measurables: List<Measurable>, constraints: Constraints): MeasureResult {
var consumedWidth = 0
var remainWidth = constraints.maxWidth

var myHeight = 0

fun consume(width: Int) {
consumedWidth += width
if (remainWidth != Constraints.Infinity) {
remainWidth -= width
}
}

fun enlarge(item: Placeable) {
// myWidth = maxOf(myWidth, item.width)
myHeight = maxOf(myHeight, item.height)
}

fun Placeable.yOffsetToCenter(): Int {
return (myHeight - height) / 2
}

val leadingPlaceable = measurables[LeadingId].measure(
Constraints(
0,
remainWidth,
constraints.minHeight,
constraints.maxHeight
)
).also {
// println("leading size = ${it.width} * ${it.height}, ${it.measuredWidth} * ${it.measuredHeight}")
consume(it.width)
enlarge(it)
}

var remainMinWidth = maxOf(0, constraints.minWidth - consumedWidth)
var remainMaxWidth = remainWidth

val textFieldPlaceable = measurables[TextFieldId].measure(
Constraints(
remainMinWidth,
remainMaxWidth,
constraints.minHeight,
constraints.maxHeight
)
).also {
enlarge(it)
}

val placeholderPlaceable = measurables[PlaceholderId].measure(
Constraints(
remainMinWidth,
remainMaxWidth,
constraints.minHeight,
constraints.maxHeight
)
).also {
enlarge(it)
}

consume(maxOf(textFieldPlaceable.width, placeholderPlaceable.height))

return layout(consumedWidth, myHeight) {
leadingPlaceable.placeRelative(0, leadingPlaceable.yOffsetToCenter())
textFieldPlaceable.placeRelative(leadingPlaceable.width, textFieldPlaceable.yOffsetToCenter())
placeholderPlaceable.placeRelative(leadingPlaceable.width, placeholderPlaceable.yOffsetToCenter())
}
}
}
)
}

0 comments on commit d528561

Please sign in to comment.