Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

157
Visualizações
LazyListState compartido en múltiples LazyRow da como resultado un comportamiento extraño

Soy nuevo en la redacción de jetpack y trato de implementar una tabla de datos desplazable usando jetpack LazyColumn/LazyRow. La primera fila y la primera columna de toda la tabla serán adhesivas.

 class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { BaseTheme { ExceptionsSpreadSheet(exceptions = generateData()) } } } }

Esta es mi actividad, BaseTheme es solo el tema predeterminado que Android Studio generó para mí.

 @OptIn(ExperimentalFoundationApi::class) @Preview(showBackground = true, widthDp = 960, heightDp = 540) @Composable fun ExceptionSpreadSheetHeader( exception: DropBoxException = DropBoxException(), state: LazyListState = rememberLazyListState() ) { LazyRow( modifier = Modifier.background(color = Color.DarkGray), state = state ) { stickyHeader { ExceptionSpreadSheetCell(text = "id") } items(1) { ExceptionSpreadSheetCell(text = "packageName") ExceptionSpreadSheetCell(text = "processName") ExceptionSpreadSheetCell(text = "packageVersionCode") ExceptionSpreadSheetCell(text = "packageVersionName") ExceptionSpreadSheetCell(text = "activity") ExceptionSpreadSheetCell(text = "romVersion") ExceptionSpreadSheetCell(text = "platformId") ExceptionSpreadSheetCell(text = "productName") ExceptionSpreadSheetCell(text = "modelName") ExceptionSpreadSheetCell(text = "exceptionSummary") ExceptionSpreadSheetCell(text = "exceptionType") ExceptionSpreadSheetCell(text = "exceptionDigest") ExceptionSpreadSheetCell(text = "androidId") ExceptionSpreadSheetCell(text = "occurTime") ExceptionSpreadSheetCell(text = "callStack") } } } @OptIn(ExperimentalFoundationApi::class) @Preview(showBackground = true, widthDp = 960, heightDp = 540) @Composable fun ExceptionSpreadSheetRow( exception: DropBoxException = DropBoxException(), state: LazyListState = rememberLazyListState() ) { LazyRow(state = state) { stickyHeader { ExceptionSpreadSheetCell( text = exception.id.toString(), modifier = Modifier.background(color = Color.DarkGray) ) } items(1) { ExceptionSpreadSheetCell(text = exception.packageName) ExceptionSpreadSheetCell(text = exception.processName) ExceptionSpreadSheetCell(text = exception.packageVersionCode) ExceptionSpreadSheetCell(text = exception.packageVersionName) ExceptionSpreadSheetCell(text = exception.activity) ExceptionSpreadSheetCell(text = exception.romVersion) ExceptionSpreadSheetCell(text = exception.platformId.toString()) ExceptionSpreadSheetCell(text = exception.productName) ExceptionSpreadSheetCell(text = exception.modelName) ExceptionSpreadSheetCell(text = exception.exceptionSummary) ExceptionSpreadSheetCell(text = exception.exceptionType) ExceptionSpreadSheetCell(text = exception.exceptionDigest) ExceptionSpreadSheetCell(text = exception.androidId) ExceptionSpreadSheetCell(text = exception.occurTime.toString()) ExceptionSpreadSheetCell(text = exception.callStack) } } }

Creé un ExceptionSpreadSheetHeader para el título adhesivo, que mostrará algunos nombres estáticos para las columnas y un ExceptionSpreadSheetRow para las filas debajo del encabezado, cada uno tiene una columna de id adhesiva.

Luego combiné estos dos componentes juntos como ``

 @OptIn(ExperimentalFoundationApi::class) @Composable fun ExceptionsSpreadSheet(exceptions: List<DropBoxException>) { val sharedScrollState = rememberLazyListState() if (sharedScrollState.isScrollInProgress) { sharedScrollState.firstVisibleItemIndex sharedScrollState.firstVisibleItemScrollOffset } LazyColumn { stickyHeader { ExceptionSpreadSheetHeader(exception = exceptions.first()) ExceptionSpreadSheetHeader(exception = exceptions.first(), state = sharedScrollState) ExceptionSpreadSheetHeader(state = sharedScrollState) ExceptionSpreadSheetRow(exception = exceptions.first(), state = sharedScrollState) ExceptionSpreadSheetRow(state = sharedScrollState) ExceptionSpreadSheetHeaderTest(state = sharedScrollState) ExceptionSpreadSheetHeaderTest(exception = exceptions.first(), state = sharedScrollState) } items(exceptions) { ExceptionSpreadSheetRow(exception = it, state = sharedScrollState) } } }

sharedScrollState para sincronizar el estado de desplazamiento horizontal en las columnas, luego encontré 2 comportamientos extraños, cualquier ayuda o explicación sería excelente para mí, gracias de antemano.

  1. en la sección de items , el estado de desplazamiento compartido no funciona al principio, solo cuando agregué la parte if (sharedScrollState.isScrollInProgress) , las filas en los items se sincronizarían; de lo contrario, parece items_not_sync . Me encantaría saber por qué funciona después de agregar la parte if o por qué no funciona antes.

  2. en la sección stickyHeaders de ExceptionsSpreadSheet , agregué muchas filas para probar, y el resultado parece header_not_sync . Las primeras 6 líneas son encabezados que agregué, incluidos los 2 rojos como ExceptionSpreadSheetHeaderTest :

 @OptIn(ExperimentalFoundationApi::class) @Preview(showBackground = true, widthDp = 960, heightDp = 540) @Composable fun ExceptionSpreadSheetHeaderTest( exception: DropBoxException = DropBoxException(), state: LazyListState = rememberLazyListState() ) { LazyRow( modifier = Modifier.background(color = Color.Red), state = state ) { stickyHeader { ExceptionSpreadSheetCell(text = "id") } items(1) { ExceptionSpreadSheetCell(text = "packageName") ExceptionSpreadSheetCell(text = "processName") ExceptionSpreadSheetCell(text = "packageVersionCode") ExceptionSpreadSheetCell(text = "packageVersionName") ExceptionSpreadSheetCell(text = "activity") ExceptionSpreadSheetCell(text = "romVersion") ExceptionSpreadSheetCell(text = "platformId") ExceptionSpreadSheetCell(text = "productName") ExceptionSpreadSheetCell(text = "modelName") ExceptionSpreadSheetCell(text = "exceptionSummary") ExceptionSpreadSheetCell(text = "exceptionType") ExceptionSpreadSheetCell(text = "exceptionDigest") ExceptionSpreadSheetCell(text = "androidId") ExceptionSpreadSheetCell(text = exception.occurTime.toString()) ExceptionSpreadSheetCell(text = "callStack") } } }

En el gif, solo el encabezado 4 y 7 se sincronizan con los contenidos a continuación, así que aquí están los comportamientos extraños:

  • en el código, el segundo encabezado ( ExceptionSpreadSheetHeader(exception = exceptions.first(), state = sharedScrollState) ) y el séptimo encabezado ( ExceptionSpreadSheetHeaderTest(exception = exceptions.first(), state = sharedScrollState) ) no tienen nada diferente, pero entre el segundo última ExceptionSpreadSheetCell en la sección de items , parece que de alguna manera tengo que usar la exception pasada, entonces la sincronización funcionaría, eso me parece realmente extraño.
  • los encabezados 6 y 7 difieren en los parámetros del constructor, el encabezado 6 usa el valor predeterminado, el encabezado 7 usa el valor asignado externo, pero dan como resultado un comportamiento de sincronización diferente.

La clase DropBoxException es una clase de datos simple

 data class DropBoxException( var id: Int = 0, var packageName: String = "", var processName: String = "", var packageVersionCode: String = "", var packageVersionName: String = "", var activity: String = "", var romVersion: String = "", var platformId: Int = -1, var productName: String = "", var modelName: String = "", var exceptionSummary: String = "", var exceptionType: String = "", var exceptionDigest: String = "", var androidId: String = "", var occurTime: Int = 0, var callStack: String = "", )

y generateData() crear algunos datos ficticios para mí

 fun generateData(): List<DropBoxException> = (1..300).map { DropBoxException( id = it, packageName = "$it packageName", processName = "$it processName" ) }

Si cree que hice un mal uso de algunas de las interfaces o si la pregunta se hizo en otro lugar antes, no dude en publicar enlaces y los investigaré, ¡gracias de nuevo!

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Después de revisar un montón de ejemplos, ahora me queda claro que cada fila/columna tendrá su propio estado. Así que aquí está mi solución actual, al hacer que lazyListState de cada fila escuche un valor mutable y cambie ese valor cuando cualquier fila se desplaza

 class MainActivity : ComponentActivity() { // ... } val horizontalFirstVisibleItemIndex = mutableStateOf(0) val horizontalFirstVisibleItemScrollOffset = mutableStateOf(0) @OptIn(ExperimentalFoundationApi::class) @Composable fun ExceptionsSpreadSheet(exceptions: List<DropBoxException>) { // ... } @OptIn(ExperimentalFoundationApi::class) @Preview(showBackground = true, widthDp = 960, heightDp = 540) @Composable fun ExceptionSpreadSheetHeader() { val scrollState = rememberLazyListState() if (scrollState.isScrollInProgress) { horizontalFirstVisibleItemIndex.value = scrollState.firstVisibleItemIndex horizontalFirstVisibleItemScrollOffset.value = scrollState.firstVisibleItemScrollOffset } LazyRow(modifier = Modifier.background(color = Color.DarkGray), state = scrollState) { // ... } LaunchedEffect(horizontalFirstVisibleItemIndex.value, horizontalFirstVisibleItemScrollOffset.value) { Log.v("test", "launch title $horizontalFirstVisibleItemScrollOffset") scrollState.scrollToItem(horizontalFirstVisibleItemIndex.value, horizontalFirstVisibleItemScrollOffset.value) } } @OptIn(ExperimentalFoundationApi::class) @Preview(showBackground = true, widthDp = 960, heightDp = 540) @Composable fun ExceptionSpreadSheetRow( exception: DropBoxException = DropBoxException(), ) { val scrollState = rememberLazyListState() if (scrollState.isScrollInProgress) { horizontalFirstVisibleItemIndex.value = scrollState.firstVisibleItemIndex horizontalFirstVisibleItemScrollOffset.value = scrollState.firstVisibleItemScrollOffset } LazyRow(state = scrollState) { // ... } LaunchedEffect(horizontalFirstVisibleItemIndex.value, horizontalFirstVisibleItemScrollOffset.value) { scrollState.scrollToItem(horizontalFirstVisibleItemIndex.value, horizontalFirstVisibleItemScrollOffset.value) } }

Espero que pueda ayudar a cualquiera que busque soluciones. Se me ocurre que hay un poco de retraso en la animación, pero lo suficientemente bueno para mi caso, por lo que no profundizaré más en este problema, pero se agradece una mayor optimización.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda