From 58a1824e8018dbf6aa68e1f53855a3e9cbf81ae5 Mon Sep 17 00:00:00 2001 From: Kevinlinpr Date: Fri, 11 Oct 2024 20:46:40 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E5=8A=A8=E7=94=BB=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aiosman/riderpro/ui/login/login.kt | 156 ++++++++++-------- 1 file changed, 85 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/com/aiosman/riderpro/ui/login/login.kt b/app/src/main/java/com/aiosman/riderpro/ui/login/login.kt index 63bf597..b4eb70d 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/login/login.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/login/login.kt @@ -1,6 +1,7 @@ package com.aiosman.riderpro.ui.login import android.content.ContentValues.TAG +import android.content.res.Resources import android.util.Log import android.widget.Toast import androidx.compose.animation.core.LinearEasing @@ -9,6 +10,10 @@ import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.rememberScrollableState +import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -23,7 +28,9 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -145,11 +152,13 @@ fun LoginPage() { Box( modifier = Modifier .fillMaxSize() - .offset( - y = (-72).dp - ), +// .offset( +// y = (-72).dp +// ), ) { - MovingImageWall() + val context = LocalContext.current // 获取 Context + MovingImageWall(context.resources) // 将 resources 传递给 MovingImageWall +// MovingImageWall() } Column( modifier = Modifier @@ -233,14 +242,18 @@ fun LoginPage() { @Composable -fun MovingImageWall() { - val imageList1 = remember { mutableStateListOf(R.drawable.wall_1_1, R.drawable.wall_1_2, R.drawable.wall_1_3) } - val imageList2 = remember { mutableStateListOf(R.drawable.wall_2_1, R.drawable.wall_2_2, R.drawable.wall_2_3) } - val imageList3 = remember { mutableStateListOf(R.drawable.wall_3_1, R.drawable.wall_3_2, R.drawable.wall_3_3) } +fun MovingImageWall(resources: Resources) { + val imageList1 = remember { mutableStateListOf(R.drawable.wall_1_1, R.drawable.wall_1_2, R.drawable.wall_1_3,R.drawable.wall_1_1, R.drawable.wall_1_2, R.drawable.wall_1_3) } + val imageList2 = remember { mutableStateListOf(R.drawable.wall_2_1, R.drawable.wall_2_2, R.drawable.wall_2_3,R.drawable.wall_2_1, R.drawable.wall_2_2, R.drawable.wall_2_3) } + val imageList3 = remember { mutableStateListOf(R.drawable.wall_3_1, R.drawable.wall_3_2, R.drawable.wall_3_3,R.drawable.wall_3_1, R.drawable.wall_3_2, R.drawable.wall_3_3) } - var offset1 by remember { mutableFloatStateOf(0f) } + val density = resources.displayMetrics.density // 获取屏幕密度 + val imageHeight = 208.dp + val imageHeightPx = imageHeight.value * density // 将 dp 转换为像素 + val resetThreshold = imageHeightPx + var offset1 by remember { mutableFloatStateOf( -resetThreshold * 3) } var offset2 by remember { mutableFloatStateOf(0f) } - var offset3 by remember { mutableFloatStateOf(0f) } + var offset3 by remember { mutableFloatStateOf( -resetThreshold * 3) } val lifecycleOwner = LocalLifecycleOwner.current val coroutineScope = rememberCoroutineScope() // 使用 rememberCoroutineScope @@ -250,13 +263,13 @@ fun MovingImageWall() { when (event) { Lifecycle.Event.ON_RESUME -> { coroutineScope.launch { // 在 coroutineScope 中启动协程 - animateImageWall(imageList1, offset1, speed = 1f) { offset1 = it } + animateImageWall(imageList1, offset1, speed = 1f, resources = resources) { offset1 = it } } coroutineScope.launch { - animateImageWall(imageList2, offset2, speed = 1.5f, reverse = true) { offset2 = it } + animateImageWall(imageList2, offset2, speed = 1.5f, reverse = true, resources = resources) { offset2 = it } } coroutineScope.launch { - animateImageWall(imageList3, offset3, speed = 2f) { offset3 = it } + animateImageWall(imageList3, offset3, speed = 2f, resources = resources) { offset3 = it } } } Lifecycle.Event.ON_PAUSE -> { @@ -271,27 +284,53 @@ fun MovingImageWall() { Box( modifier = Modifier - .fillMaxSize() - .offset(y = (-72).dp) - ) { - - Row (modifier = Modifier .fillMaxWidth() - .height(700.dp)){ +// .height(5000.dp) +// .offset(y = (-72).dp) + ) { + val scrollState1 = rememberScrollState() + val scrollableState1 = rememberScrollableState { delta -> + // 消耗所有滚动事件,阻止用户滚动 + delta + } + val scrollState2 = rememberScrollState() + val scrollableState2 = rememberScrollableState { delta -> + // 消耗所有滚动事件,阻止用户滚动 + delta + } + val scrollState3 = rememberScrollState() + val scrollableState3 = rememberScrollableState { delta -> + // 消耗所有滚动事件,阻止用户滚动 + delta + } + Row (modifier = Modifier + .fillMaxWidth()){ // 第1列 ImageColumn(imageList1, offset1, Modifier - .fillMaxHeight() + .verticalScroll(scrollState1) + .scrollable( + state = scrollableState1, + orientation = Orientation.Vertical + ) .weight(1f)) // 第2列 ImageColumn(imageList2, offset2, Modifier - .fillMaxHeight() + .verticalScroll(scrollState2) + .scrollable( + state = scrollableState2, + orientation = Orientation.Vertical + ) .weight(1f), reverse = true) // 第3列 ImageColumn(imageList3, offset3, Modifier - .fillMaxHeight() + .verticalScroll(scrollState3) + .scrollable( + state = scrollableState3, + orientation = Orientation.Vertical + ) .weight(1f)) } @@ -346,11 +385,11 @@ fun ImageColumn( offset } // 检查是否超出屏幕范围 - if (translation < -imageHeight.value) { // 移出屏幕底部 - translation += totalHeight - } else if (translation > totalHeight) { // 移出屏幕顶部 - translation -= totalHeight - } +// if (translation < -imageHeight.value * 3) { // 移出屏幕底部 +//// translation += (imageHeight.value * 3) +// } else if (translation > (totalHeight / 2)) { // 移出屏幕顶部 +// translation -= (totalHeight / 2) +// } translationY = translation } .clip(RoundedCornerShape(16.dp)), @@ -370,68 +409,43 @@ fun ImageColumn( } } } - suspend fun animateImageWall( imageList: MutableList, initialOffset: Float, - speed: Float, + speed: Float, // speed 现在以像素为单位 reverse: Boolean = false, + resources: Resources, // 添加 resources 参数 onUpdate: (Float) -> Unit, ) { + val density = resources.displayMetrics.density // 获取屏幕密度 var currentOffset = initialOffset val imageCount = imageList.size val imageHeight = 208.dp - var currentIndex = 0 // 添加一个变量来跟踪当前显示的图片索引 + val imageHeightPx = imageHeight.value * density // 将 dp 转换为像素 + val resetThreshold = imageHeightPx + Log.d(TAG, "speed: $speed") + Log.d(TAG, "resetThreshold: $resetThreshold") while (true) { onUpdate(currentOffset) if (reverse) { currentOffset -= speed - if (currentOffset < -imageHeight.value * (imageCount - 1)) { -// val firstImage = imageList.first() // 将第一个元素移除 -// imageList.add(firstImage) // 将第一个元素添加到末尾 - currentOffset += imageHeight.value * imageCount // 将图片移动到末尾 -// currentIndex = (currentIndex - 1 + imageCount) % imageCount // 反向旋转 +// Log.d(TAG, "currentOffset: $currentOffset") + if (currentOffset <= -resetThreshold * 3) { // 检查是否向上超出阈值 + // 使用 imageHeightPx 进行计算 + // 复位 + currentOffset = initialOffset } } else { currentOffset += speed - if (currentOffset > imageHeight.value * (imageCount - 1)) { -// val lastImage = imageList.last() // 将最后一个元素移除 -// imageList.add(0, lastImage) // 将最后一个元素添加到开头 - currentOffset -= imageHeight.value * imageCount // 将图片移动到开头 -// currentIndex = (currentIndex + 1) % imageCount // 正向旋转 + + if (currentOffset >= 0) { // 检查是否向上超出阈值 + Log.d(TAG, "currentOffset: $currentOffset") + // 使用 imageHeightPx 进行计算 + // 复位 + currentOffset = initialOffset } + // 使用 imageHeightPx 进行计算 } - // 更新 ImageColumn 中的 currentImage -// onUpdate(currentIndex.toFloat()) // 将当前索引传递给 onUpdate delay(16) } -} - -// 计算图片的透明度 -private fun calculateAlpha( - offset: Float, - index: Int, - imageHeight: Float, - totalHeight: Float, - reverse: Boolean -): Float { - val offsetDp = if (reverse) { - -offset - } else { - offset - } - val imageTop = index * imageHeight - val imageBottom = imageTop + imageHeight - return when { - offsetDp in imageTop..imageBottom -> { - (offsetDp - imageTop) / imageHeight - } - (offsetDp + totalHeight) in imageTop..imageBottom -> { // 考虑循环滚动的情况 - (offsetDp + totalHeight - imageTop) / imageHeight - } - (offsetDp - totalHeight) in imageTop..imageBottom -> { // 考虑循环滚动的情况 - (offsetDp - totalHeight - imageTop) / imageHeight - } - else -> 0f - } } \ No newline at end of file