Как сделать плавную анимацию в Android Compose для расширения TextField?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как сделать плавную анимацию в Android Compose для расширения TextField?

Сообщение Anonymous »

У меня есть собственное TextField в Jetpack Compose, которое расширяется от одной строки до двух строк в зависимости от состояния фокуса. В настоящее время переход резкий, и я хочу сделать его плавным.
Когда состояние фокуса в моем TextField меняется, я перехожу от макета строки к макету столбца. Однако, несмотря на то, что я использую тот же компонент RightIcon, во время перехода он прыгает, а не движется плавно.
Вот моя текущая реализация:
InputTextField:
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun InputTextField() {
var textState by remember { mutableStateOf("") }
var hasFocus by remember { mutableStateOf(false) }

val transition = updateTransition(
targetState = hasFocus || textState.isNotEmpty(),
label = "expandTransition"
)
val chatInputTextField = @Composable {
ChatInputTextField(
textState = textState,
onValueChange = { textState = it },
onFocusChanged = { focusState ->
if (hasFocus != focusState.isFocused) {
hasFocus = focusState.isFocused
Log.i("InputTextField", "hasFocus changed to: $hasFocus")
}
}
)
}

Box(
modifier = Modifier
.fillMaxWidth()
.background(color = Color.White)
.border(
width = 1.dp,
color = Color.Gray,
shape = RoundedCornerShape(8.dp)
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp)
) {
Row(
Modifier
.fillMaxWidth()
.background(Color.Red.copy(alpha = 0.5f))
.padding(vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
LeftIcon()
Box(modifier = Modifier.weight(1f)) {
chatInputTextField()
}
transition.AnimatedVisibility(
visible = { !it },
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(0))
) {
RightIcon()
}
}

transition.AnimatedVisibility(
visible = { it },
enter = fadeIn(
animationSpec = tween(
durationMillis = 150,
delayMillis = 150
)
) + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
Row(
Modifier
.fillMaxWidth()
.background(Color.Yellow.copy(alpha = 0.5f))
.padding(start = 12.dp, bottom = 12.dp, top = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
RightIcon()
}
}
}
}
}

@Composable
fun ChatInputTextField(
textState: String,
onValueChange: (String) -> Unit,
onFocusChanged: (FocusState) -> Unit = {},
) {
val scrollState = rememberScrollState()

BasicTextField(
value = textState,
onValueChange = onValueChange,
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState)
.onFocusChanged { focusState ->
onFocusChanged(focusState)
},
textStyle = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
letterSpacing = 0.sp,
),
singleLine = false,
)
}

@Composable
private fun LeftIcon() {
Box(
modifier = Modifier
.padding(end = 12.dp)
) {
Icon(
imageVector = Icons.Default.Face,
contentDescription = null,
modifier = Modifier
.size(28.dp)
)
}
}

@Composable
private fun RightIcon() {
Row(
modifier = Modifier
.background(Color.Blue),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = null,
modifier = Modifier
.size(24.dp),
tint = Color.Gray
)
}
}

MainActivity:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyApplicationTheme {
val focusManager = LocalFocusManager.current
Scaffold(
modifier = Modifier.fillMaxSize(),
containerColor = Color.White
) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
focusManager.clearFocus()
}
)
},
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier.fillMaxWidth().padding(horizontal = 12.dp)
) {
InputTextField()

}
}
}
}
}
}
}```

This is the display effect

[enter image description here](https://i.sstatic.net/GyCooDQE.gif)

How to maintain a single instance of a button component during layout transition in Jetpack Compose?



Подробнее здесь: https://stackoverflow.com/questions/793 ... -textfield
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»