Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

156
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!