У меня есть собственное 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
Как сделать плавную анимацию в Android Compose для расширения TextField? ⇐ Android
Форум для тех, кто программирует под Android
1735993647
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?
Подробнее здесь: [url]https://stackoverflow.com/questions/79328838/how-to-make-smooth-animations-in-android-compose-for-expanding-textfield[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия