欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

AndroidJetpackCompose实现列表吸顶效果,

来源: 开发者 投稿于  被查看 28026 次 评论:187

AndroidJetpackCompose实现列表吸顶效果,


目录
  • stickyHeader
  • 实体类
    • 加载假数据
  • 吸顶标题
    • 二级条目
      • 完整代码
        • 效果图

          安卓传统的 Recyclerview 打造悬浮头部StickyHeader的吸顶效果,十分麻烦,而在Compose中就简单多了

          stickyHeader

          Compose设计的时候考虑得很周到,他们提供了stickyHeader

          作用就是添加一个粘性标题项,即使在它后面滚动时也会保持固定。标头将保持固定,直到下一个标头取而代之。

          参数key - 表示唯一的密钥键。

          它不允许对列表出现使用相同的键。密钥的类型应该可以通过 Bundle 保存。如果传递了 null,则列表中的位置将代表键。当指定键时,滚动位置将基于该键保持,这意味着如果在当前可见项目之前添加删除项目,则具有给定键的项目将保留为第一个可见项目。

          参数content 传入Composable控件就即可显示

          实体类

          创建一个实体类标题和内容

          data class Post(
              val title:String,
              val contentData:List<String>
          )

          加载假数据

          val list : MutableList<Post> = mutableListOf()
          for (index in 1..10) {
              val contentData :MutableList<String> = mutableListOf()
              for (i in 1..30){
                  contentData.add("内容 $i")
              }
              list.add(Post("标题$index",contentData))
          }

          定义一个垂直滚动列表,仅构成和布局当前可见的项目

          LazyColumn {
              list.forEachIndexed { position, post ->
                  stickyHeader {
                      ListTitle(title = post.title)
                  }
          
                  items(post.contentData.size) { route ->
                      StructureItem(post.contentData)
                  }
                  if (position <= list.size - 1) {
                      Divider()
                  }
                  Spacer(modifier = Modifier.height(10.dp))
              }
          }

          吸顶标题

          接着封装一个吸顶标题,并传出点击事件

          @Composable
          fun ListTitle(
              onSubtitleClick: () -> Unit = {}
          ) {
                  MediumTitle(
                      title = title,
                      modifier = Modifier.align(Alignment.CenterVertically).clickable {
                          onSubtitleClick.invoke()
                      }
          }

          效果图

          二级条目

          接着写二级条目

          FlowRow可以将其子项置于水平流中的可组合项。如果水平空间太小而无法将所有子项放在一行中,则可能会使用多行。传统的流式布局

          用法很简单,和row一样

          FlowRow {
              for (item in bean) {
                  TextButton(
                     ....
                  }
              }
          }

          在content可组控件里面添加多个TextButton即可

          fun StructureItem{
              Column{
                  FlowRow() {
                      for (item in bean) {
                          TextButton
                          {
                              Text()
                          }
          
                      }
                  }
          
              }
          }

          效果图

          接着吸顶标题放在LazyColumn里面就完成了

          LazyColumn() {
              list.forEachIndexed { position, post ->
                  stickyHeader {
                      ListTitle(title = post.title) {
                          //点击事件
                      }
                  }
                  item {
                      StructureItem(post.contentData)
                      Spacer(modifier = Modifier.height(10.dp))
                  }
              }
          }

          完整代码

          @OptIn(ExperimentalFoundationApi::class)
          @Composable
          fun StickyHeaderScreen() {
              val list: MutableList<Post> = mutableListOf()
              for (index in 1..10) {
                  val contentData: MutableList<String> = mutableListOf()
                  for (i in 1..12) {
                      contentData.add("内容 $i")
                  }
                  list.add(Post("标题$index", contentData))
              }
              LazyColumn(
                  modifier = Modifier
                      .fillMaxWidth()
                      .fillMaxHeight(),
                  contentPadding = PaddingValues(vertical = 10.dp)
              ) {
                  list.forEachIndexed { position, post ->
                      stickyHeader {
                          ListTitle(title = post.title) {
                              //点击事件
                          }
                      }
                      item {
                          StructureItem(post.contentData)
                          Spacer(modifier = Modifier.height(10.dp))
                      }
                  }
              }
          }
          
          data class Post(
              val title: String,
              val contentData: List<String>
          )
          
          @Composable
          fun ListTitle(
              modifier: Modifier = Modifier,
              title: String,
              isLoading: Boolean = false,
              onSubtitleClick: () -> Unit = {}
          ) {
              Row(
                  modifier = modifier
                      .placeholder(false)
                      .fillMaxWidth()
                      .height(ListTitleHeight)
                      .background(color = Color.Gray)
              ) {
                  Box(
                      modifier = Modifier
                          .padding(horizontal = 10.dp)
                          .width(5.dp)
                          .height(16.dp)
                          .align(Alignment.CenterVertically)
                          .background(color = Color.Black)
                  )
                  MediumTitle(
                      title = title,
                      color = Color.Black,
                      modifier = Modifier.align(Alignment.CenterVertically).clickable {
                          onSubtitleClick.invoke()
                      },
                      isLoading = isLoading
                  )
                  Spacer(modifier = Modifier.weight(1f))
              }
          
          }
          
          
          @Composable
          fun StructureItem(
              bean: List<String>
          ) {
              Column(
                  modifier = Modifier
                      .fillMaxWidth()
                      .padding(top = 10.dp)
              ) {
          
                  FlowRow(
                      modifier = Modifier.padding(horizontal = 6.dp)
                  ) {
          
          
                      for (item in bean) {
                          Box(modifier = Modifier.padding(horizontal = 2.dp, vertical = 3.dp)) {
                              TextButton(
                                  modifier = Modifier.padding(horizontal = 3.dp).height(34.dp),
                                  shape = RoundedCornerShape(12.dp),
                                  onClick = { },
                                  colors = ButtonDefaults.textButtonColors(
                                      backgroundColor = themeColor
                                  )
                              )
                              {
                                  Text(
                                      item,
                                      color = Color.White
                                  )
                              }
          
                          }
                      }
                  }
          
              }
          }

          效果图

          左边的黑边是我裁剪的问题,抱歉啦!

          到此这篇关于Android Jetpack Compose实现列表吸顶效果的文章就介绍到这了,更多相关Jetpack Compose列表吸顶内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

          您可能感兴趣的文章:
          • Android Jetpack Compose无限加载列表
          • Android实现recyclerview城市字母索引列表
          • 利用Jetpack Compose实现主题切换功能
          • 通过Jetpack Compose实现双击点赞动画效果
          • 利用Jetpack Compose绘制可爱的天气动画

          用户评论