kotlin 从发生的事件组成

dzhpxtsq  于 2023-10-23  发布在  Kotlin
关注(0)|答案(2)|浏览(144)

我在这里传递的lambda是为了帮助防止重新组合titleTextLayoutResult: (hasVisualOverflow: Boolean, lineCount: Int) -> Boolean
由于这是一个LazyColumn,每次用户上下滚动时,它都会创建大量的重组。
我想是因为这个

  1. onTextLayout = { textLayoutResult ->
  2. shouldShowMoreTitle = titleTextLayoutResult(textLayoutResult.hasVisualOverflow, textLayoutResult.lineCount)
  3. })

我把它提取到一个lambda函数中,认为这可能会有所帮助,但它仍然是一样的。只是想知道有没有解决这个问题的办法?
我在下面添加了一些片段。但这是存储库,以防代码片段中缺少某些内容。
https://github.com/steve1rm/BusbyNews

  1. var shouldShowMoreTitle by remember {
  2. mutableStateOf(false)
  3. }
  4. @Composable
  5. fun NewsItem(
  6. modifier: Modifier = Modifier,
  7. articleModel: ArticleModel,
  8. onNewsLinkClicked: (newsLink: String) -> Unit,
  9. newsItemEvent: (NewsItemEvent) -> Unit,
  10. newsItemState: NewsItemState,
  11. titleTextLayoutResult: (hasVisualOverflow: Boolean, lineCount: Int) -> Boolean
  12. ) {
  13. Text(
  14. modifier = Modifier
  15. .fillMaxWidth()
  16. .animateContentSize(),
  17. color = MaterialTheme.colorScheme.onSurface,
  18. style = MaterialTheme.typography.titleMedium,
  19. text = articleModel.title,
  20. maxLines = if (showMoreTitleClicked) Int.MAX_VALUE else 1,
  21. overflow = TextOverflow.Ellipsis,
  22. onTextLayout = { textLayoutResult ->
  23. shouldShowMoreTitle = titleTextLayoutResult(textLayoutResult.hasVisualOverflow, textLayoutResult.lineCount)
  24. })
  25. }
  26. NewsItem(
  27. articleModel = articleModel,
  28. onNewsLinkClicked = onNewsLinkedClicked,
  29. newsItemEvent = newsItemEvent,
  30. newsItemState = newsItemState,
  31. titleTextLayoutResult = ::getTextLayoutResult)
  32. private fun getTextLayoutResult(hasVisualOverflow: Boolean, lineCount: Int): Boolean {
  33. return hasVisualOverflow || lineCount > 1
  34. }

我已经为lazy列使用了一个键,如下所示:

  1. LazyColumn(
  2. modifier = Modifier.fillMaxWidth(),
  3. contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 8.dp),
  4. verticalArrangement = Arrangement.spacedBy(6.dp),
  5. horizontalAlignment = Alignment.CenterHorizontally
  6. ) {
  7. items(
  8. key = { articleModel ->
  9. articleModel.id
  10. },
  11. items = newsPagingData.itemSnapshotList.items
  12. ) { articleModel ->
  13. NewsItem(
  14. articleModel = articleModel,
  15. onNewsLinkClicked = onNewsLinkedClicked,
  16. newsItemEvent = newsItemEvent,
  17. newsItemState = newsItemState,
  18. titleTextLayoutResult = ::getTextLayoutResult
  19. )
  20. }
  21. }

这是重组

yc0p9oo0

yc0p9oo01#

主要问题是NewsState,MainActivity中的newsItemEvent也有问题。
首先从NewsItemshouldShowProgress中删除NewState作为布尔值

  1. @Composable
  2. fun NewsItem(
  3. modifier: Modifier = Modifier,
  4. articleModel: ArticleModel,
  5. onNewsLinkClicked: (newsLink: String) -> Unit,
  6. newsItemEvent: (NewsItemEvent) -> Unit,
  7. shouldShowProgress:Boolean = false,
  8. // newsItemState: NewsItemState,
  9. titleTextLayoutResult: (hasVisualOverflow: Boolean, lineCount: Int) -> Boolean
  10. )

然后在setContent中通过设置

  1. val lambda = remember {
  2. { newsItemEvent: NewsItemEvent ->
  3. newsViewModel.onNewsItemEvent(newsItemEvent)
  4. }
  5. }
  6. val themeLambda = remember {
  7. { appTheme:AppTheme->
  8. newsApplication.toggleDarkThemeOff(appTheme)
  9. }
  10. }

打电话给新闻网

  1. NewsScreen(
  2. newsPagingData = newsHeadLines,
  3. modifier = Modifier
  4. .fillMaxSize()
  5. .nestedScroll(connection = scrollBehavior.nestedScrollConnection),
  6. topAppBarScrollBehavior = scrollBehavior,
  7. onNewsLinkedClicked = { newsLink ->
  8. newsLinkState = newsLink
  9. },
  10. newsItemState = newsItemState,
  11. newsItemEvent = { newsItemEvent ->
  12. // newsViewModel.onNewsItemEvent(newsItemEvent)
  13. lambda.invoke(newsItemEvent)
  14. },
  15. selectedTheme = useDarkColors,
  16. onSelectedTheme = { appTheme ->
  17. // newsApplication.toggleDarkThemeOff(appTheme)
  18. themeLambda(appTheme)
  19. }
  20. )

这些将消除NewsItem重组,但LazyColumn将被重组,因为NewsItemItems读取NewsState。我还在NewsItemsItems中创建了一个lambda,但这是可选的,我不认为它在任何情况下都有效。

  1. val textLayoutResultLambda = remember {
  2. { hasVisualOverflow: Boolean, lineCount: Int ->
  3. getTextLayoutResult(hasVisualOverflow, lineCount)
  4. }
  5. }

我还更新了NewState,删除了可变参数,但无论如何它仍然会触发重组。你应该关注为什么NewsState触发了不必要的重组。

  1. @Immutable
  2. data class NewsItemState(
  3. val shouldShowProgress: Boolean = false,
  4. val showMoreOrLessTitleText: ShowMoreOrLessTitleText = ShowMoreOrLessTitleText(),
  5. // val showMoreTitleClicked: Boolean = false,
  6. val shouldShowMoreTitle: Boolean = true,
  7. val shouldMoreDescriptionClicked: Boolean = false,
  8. val shouldShowMoreDescription: Boolean = false,
  9. val isDarkThemeSelected: Boolean = false
  10. )
  11. /** Work in-progress*/
  12. data class ShowMoreOrLessTitleText(
  13. val text: String = "Show more",
  14. val shouldShowMoreTitle: Boolean = false,
  15. val hasTextOverflow: Boolean = false,
  16. val lineCount: Int = -1
  17. )
  18. fun ShowMoreOrLessTitleText.textUpdate(): String {
  19. return if(this.shouldShowMoreTitle)
  20. "Show more"
  21. else
  22. "Show less"
  23. }
  24. fun ShowMoreOrLessTitleText.shouldMoreText(): Boolean {
  25. return this.hasTextOverflow || lineCount > 1
  26. }

在ViewModel中,您可以将其更新为

  1. is NewsItemEvent.OnShowMoreTitleTextClicked -> {
  2. _newsItemState.update { newsItemState ->
  3. val showMoreOrLessTitleText = newsItemState.showMoreOrLessTitleText.copy(
  4. lineCount = newsItemEvent.showMoreOrLessTitleText.lineCount,
  5. hasTextOverflow = newsItemEvent.showMoreOrLessTitleText.hasTextOverflow,
  6. shouldShowMoreTitle = newsItemState.showMoreOrLessTitleText.shouldMoreText(),
  7. text = newsItemState.showMoreOrLessTitleText.textUpdate(),
  8. )
  9. newsItemState.copy(
  10. showMoreOrLessTitleText = showMoreOrLessTitleText
  11. )
  12. }
  13. }
展开查看全部
t2a7ltrp

t2a7ltrp2#

这样做一个rememberLazyListState

  1. val lazyColumnListState = rememberLazyListState()

然后将它传递给LazyColumn,如下所示:

  1. LazyColumn(
  2. state = lazyColumnListState,
  3. modifier = Modifier.fillMaxWidth(),
  4. contentPadding = PaddingValues(start = 8.dp, end = 8.dp, top = 8.dp),
  5. verticalArrangement = Arrangement.spacedBy(6.dp),
  6. horizontalAlignment = Alignment.CenterHorizontally
  7. ) {
  8. items(
  9. key = { articleModel ->
  10. articleModel.id
  11. },
  12. items = newsPagingData.itemSnapshotList.items
  13. ) { articleModel ->
  14. NewsItem(
  15. articleModel = articleModel,
  16. onNewsLinkClicked = onNewsLinkedClicked,
  17. newsItemEvent = newsItemEvent,
  18. newsItemState = newsItemState,
  19. titleTextLayoutResult = ::getTextLayoutResult
  20. )
  21. }
  22. }
展开查看全部

相关问题