Я использовал следующий код в Jetpack Compose, чтобы расположить элементы в центре экрана, и мне это удалось, но когда я нажимаю на элемент, элемент перемещается вниз, и эффект flingBehavior исчезает. Кроме того, элемент расположен немного ниже точного центра.
Я хочу, чтобы ширина элементов была фиксированной, но их высота была равна WrapContentHeight(), поэтому я сделал это таким образом. Я не хочу фиксировать их на определенной высоте.
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyProductMenuCards(
navController: NavController,
categoryIndex: Int,
darkTheme: Boolean,
clicked: (Boolean) -> Unit,
productCount: (Int) -> Unit,
onCenterColorChanged: (Color) -> Unit,
onCenterImageChanged: (Int) -> Unit
) {
val viewModel: ProductsViewModel = hiltViewModel()
val list by viewModel.productsState.collectAsState()
val density = LocalDensity.current
val state = rememberLazyListState()
val context = LocalContext.current
val snappingLayout = remember(state) { SnapLayoutInfoProvider(state) }
val flingBehavior = rememberSnapFlingBehavior(snappingLayout)
val coroutineScope = rememberCoroutineScope()
val filteredList by remember {
derivedStateOf {
val selectedCategory = if (categoryIndex == 0) Category.Yemekler else Category.Icecekler
list.filter { it.category == selectedCategory }
}
}
productCount(filteredList.size)
var clicked by remember { mutableStateOf(null) }
var selectedIndex by remember { mutableStateOf(-1) }
var columnHeight by remember { mutableStateOf(0) }
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
val itemHeights = remember { mutableStateMapOf() }
// Snap position'ı takip et
val centeredItemIndex by remember(state.firstVisibleItemIndex, state.firstVisibleItemScrollOffset) {
derivedStateOf {
val visibleItems = state.layoutInfo.visibleItemsInfo
if (visibleItems.isEmpty()) return@derivedStateOf -1
val firstVisible = state.firstVisibleItemIndex
val scrollOffset = state.firstVisibleItemScrollOffset
if (scrollOffset > visibleItems.firstOrNull()?.size?.div(2) ?: 0) {
firstVisible + 1
} else {
firstVisible
}
}
}
LaunchedEffect(centeredItemIndex) {
if (centeredItemIndex != -1) {
selectedIndex = centeredItemIndex
}
}
// Seçili index'i güncelle
val currentSelectedIndex = if (selectedIndex != -1) selectedIndex else centeredItemIndex
// Merkezdeki öğenin yüksekliğine göre padding hesapla
val verticalPadding by remember(columnHeight, currentSelectedIndex) {
derivedStateOf {
if (columnHeight > 0 && currentSelectedIndex >= 0) {
val centerItemHeight = itemHeights[currentSelectedIndex] ?: 0
if (centerItemHeight > 0) {
((columnHeight - centerItemHeight) / 2).coerceAtLeast(0)
} else {
0
}
} else {
0
}
}
}
Box {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.onGloballyPositioned { columnHeight = it.size.height },
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
state = state,
flingBehavior = flingBehavior,
contentPadding = PaddingValues(vertical = with(density) { verticalPadding.toDp() })
) {
items(count = filteredList.size) { index ->
if (!darkTheme) {
MyProductMenuCard(
state = state,
currentSelectedIndex = currentSelectedIndex,
index = index,
productModel = filteredList[index],
clicked = (clicked == filteredList[index]),
onFavoriteUpdate = {
viewModel.updateProduct(it)
},
onCardClick = {
coroutineScope.launch {
state.animateScrollToItem(index)
selectedIndex = index
val productJson = Gson().toJson(filteredList[index])
val encodedJson = URLEncoder.encode(productJson, StandardCharsets.UTF_8.name())
navController.navigate("detaysayfa/$encodedJson")
}
},
onHeightMeasured = { height ->
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
itemHeights[index] = height
}
)
} else {
MyProductMenuCardDarkTheme(
state = state,
index = index,
productModel = filteredList[index],
onFavoriteUpdate = {
viewModel.updateProduct(it)
},
onCardClick = {
coroutineScope.launch {
val layoutInfo = state.layoutInfo
val center = (layoutInfo.viewportStartOffset + layoutInfo.viewportEndOffset) / 2
val itemInfo = layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
itemInfo?.let {
val targetOffset = (it.offset + it.size / 2 - center).toFloat()
state.animateScrollBy(targetOffset)
} ?: run {
state.animateScrollToItem(index)
}
val productJson = Gson().toJson(filteredList[index])
val encodedJson = URLEncoder.encode(productJson, StandardCharsets.UTF_8.name())
navController.navigate("detaysayfa/$encodedJson")
}
},
onHeightMeasured = { height ->
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
itemHeights[index] = height
}
)
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... ck-compose
Проблема LazyColumn flingBehavior в Jetpack Compose ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1763722964
Anonymous
Я использовал следующий код в Jetpack Compose, чтобы расположить элементы в центре экрана, и мне это удалось, но когда я нажимаю на элемент, элемент перемещается вниз, и эффект flingBehavior исчезает. Кроме того, элемент расположен немного ниже точного центра.
Я хочу, чтобы ширина элементов была фиксированной, но их высота была равна WrapContentHeight(), поэтому я сделал это таким образом. Я не хочу фиксировать их на определенной высоте.
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyProductMenuCards(
navController: NavController,
categoryIndex: Int,
darkTheme: Boolean,
clicked: (Boolean) -> Unit,
productCount: (Int) -> Unit,
onCenterColorChanged: (Color) -> Unit,
onCenterImageChanged: (Int) -> Unit
) {
val viewModel: ProductsViewModel = hiltViewModel()
val list by viewModel.productsState.collectAsState()
val density = LocalDensity.current
val state = rememberLazyListState()
val context = LocalContext.current
val snappingLayout = remember(state) { SnapLayoutInfoProvider(state) }
val flingBehavior = rememberSnapFlingBehavior(snappingLayout)
val coroutineScope = rememberCoroutineScope()
val filteredList by remember {
derivedStateOf {
val selectedCategory = if (categoryIndex == 0) Category.Yemekler else Category.Icecekler
list.filter { it.category == selectedCategory }
}
}
productCount(filteredList.size)
var clicked by remember { mutableStateOf(null) }
var selectedIndex by remember { mutableStateOf(-1) }
var columnHeight by remember { mutableStateOf(0) }
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
val itemHeights = remember { mutableStateMapOf() }
// Snap position'ı takip et
val centeredItemIndex by remember(state.firstVisibleItemIndex, state.firstVisibleItemScrollOffset) {
derivedStateOf {
val visibleItems = state.layoutInfo.visibleItemsInfo
if (visibleItems.isEmpty()) return@derivedStateOf -1
val firstVisible = state.firstVisibleItemIndex
val scrollOffset = state.firstVisibleItemScrollOffset
if (scrollOffset > visibleItems.firstOrNull()?.size?.div(2) ?: 0) {
firstVisible + 1
} else {
firstVisible
}
}
}
LaunchedEffect(centeredItemIndex) {
if (centeredItemIndex != -1) {
selectedIndex = centeredItemIndex
}
}
// Seçili index'i güncelle
val currentSelectedIndex = if (selectedIndex != -1) selectedIndex else centeredItemIndex
// Merkezdeki öğenin yüksekliğine göre padding hesapla
val verticalPadding by remember(columnHeight, currentSelectedIndex) {
derivedStateOf {
if (columnHeight > 0 && currentSelectedIndex >= 0) {
val centerItemHeight = itemHeights[currentSelectedIndex] ?: 0
if (centerItemHeight > 0) {
((columnHeight - centerItemHeight) / 2).coerceAtLeast(0)
} else {
0
}
} else {
0
}
}
}
Box {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.onGloballyPositioned { columnHeight = it.size.height },
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
state = state,
flingBehavior = flingBehavior,
contentPadding = PaddingValues(vertical = with(density) { verticalPadding.toDp() })
) {
items(count = filteredList.size) { index ->
if (!darkTheme) {
MyProductMenuCard(
state = state,
currentSelectedIndex = currentSelectedIndex,
index = index,
productModel = filteredList[index],
clicked = (clicked == filteredList[index]),
onFavoriteUpdate = {
viewModel.updateProduct(it)
},
onCardClick = {
coroutineScope.launch {
state.animateScrollToItem(index)
selectedIndex = index
val productJson = Gson().toJson(filteredList[index])
val encodedJson = URLEncoder.encode(productJson, StandardCharsets.UTF_8.name())
navController.navigate("detaysayfa/$encodedJson")
}
},
onHeightMeasured = { height ->
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
itemHeights[index] = height
}
)
} else {
MyProductMenuCardDarkTheme(
state = state,
index = index,
productModel = filteredList[index],
onFavoriteUpdate = {
viewModel.updateProduct(it)
},
onCardClick = {
coroutineScope.launch {
val layoutInfo = state.layoutInfo
val center = (layoutInfo.viewportStartOffset + layoutInfo.viewportEndOffset) / 2
val itemInfo = layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
itemInfo?.let {
val targetOffset = (it.offset + it.size / 2 - center).toFloat()
state.animateScrollBy(targetOffset)
} ?: run {
state.animateScrollToItem(index)
}
val productJson = Gson().toJson(filteredList[index])
val encodedJson = URLEncoder.encode(productJson, StandardCharsets.UTF_8.name())
navController.navigate("detaysayfa/$encodedJson")
}
},
onHeightMeasured = { height ->
// HER ÖĞENIN YÜKSEKLİĞİNİ SAKLA
itemHeights[index] = height
}
)
}
}
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79826428/lazycolumn-flingbehavior-problem-in-jetpack-compose[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия