【问题标题】:Using Horizontal LazyRow with items in compose将 Horizo​​ntal LazyRow 与 compose 中的项目一起使用
【发布时间】:2022-08-03 17:37:25
【问题描述】:

我正在尝试找出创建此类设计的最佳方法:https://gyazo.com/bae04894f7ef079a06ad71f733026f33

https://gyazo.com/111eace0d8cdecdecad1c8a7b486faf7

我应该按照滚动视图的建议使用 Horizo​​ntallazyRow 还是我将如何去做?我是否还应该为 placeholdercard 中的每个项目创建 1 个可组合项,或者是否有更有效的方法来使用较新版本的 jetpack compose?感谢反馈!

这是到目前为止的代码:


@Composable
fun MainContent(
    placeholderItems: List<String>
) {

    val lazyListState: LazyListState = rememberLazyListState()

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {

        Text(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            text = \"Example Horizontal LazyRow\"
        )

        LazyRow(
            modifier = Modifier.fillMaxWidth(),
            contentPadding = PaddingValues(8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {

            items(items = placeholderItems) { itemMessage: String ->
                PlaceholderCard(itemMessage)
            }
        }
    }
}

更新的答案这设法解决了问题!谢谢:
@Sadegh.t 建议! - 不得不做一些 tweeks 但现在它完全有效!


data class Items(
    val num: Int,
    val id: UUID = UUID.randomUUID()
)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ItemView(modifier: Modifier = Modifier, title: String, selected:
Boolean = false) {
    Card(
        modifier = if (!selected) modifier
            .height(80.dp)
            .width(95.dp)
        else modifier
            .height(100.dp)
            .width(120.dp),
        shape = RoundedCornerShape(16.dp),
        elevation = if (selected) CardDefaults.cardElevation(24.dp ) else CardDefaults.cardElevation(4.dp)
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {

            Text(text = title, modifier = Modifier.fillMaxWidth()
                , textAlign =  TextAlign.Center)
        }
    }
}

@Composable
fun NumberList(list: List<Items>) {

    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {

        LazyRow(state = rememberLazyListState()) {

            items(50, key = { it }) {
                if (it == 2) {
                    ItemView(
                        title = it.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                            .height(80.dp)
                        , selected = true
                    )
                }else {
                    ItemView(
                        title = it.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                    )
                }
            }
        }
    }
}

  • 这回答了你的问题了吗? Snap to an index Lazyrow
  • 我认为您的问题更侧重于捕捉屏幕中心的项目,而我的问题是创建一个包含各种项目的功能性 LazyRow。我确实发现捕捉机制很有趣,因此也会对其进行更多研究:) 感谢您的建议!

标签: android kotlin android-jetpack-compose scrollable lazycolumn


【解决方案1】:

您可以试试这个,创建一个 LazyRow ,然后检查该项目是否被选中

@Composable 
fun NumberList(list: List<Items>) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
        LazyRow(state = rememberLazyListState()) {
            items(list, key = { it.id }) {
                if (it.num == 2) {
                    ItemView(
                        title = it.num.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                            .height(80.dp)
                    , selected = true
                    )
                }else {
                    ItemView(
                        title = it.num.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                    )
                }
            }
        }
    }
}

对于该项目:

@Composable
fun ItemView(modifier: Modifier = Modifier, title: String, selected: 
    Boolean = false) {
    Card(
        modifier = if (!selected) modifier
            .height(80.dp)
            .width(95.dp)
        else modifier
            .height(100.dp)
            .width(120.dp),
        shape = RoundedCornerShape(16.dp),
        elevation = if (selected) 24.dp else 4.dp
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {

            Text(text = title, modifier = Modifier.fillMaxWidth()
            , textAlign =  TextAlign.Center)
        }
    }
}

更新:我使用了这个数据类,你可以使用自己的数据类,也不需要使用 Id。

data class Items(val num: Int, val id: UUID = UUID.randomUUID())

【讨论】:

  • 唯一的问题是我收到一条带有 id 和 num 的错误消息,它显示为 Unresolved reference。
  • 我必须做一些额外的更改,例如使用 Cardelevation + 指定列表中有多少项目(将它们作为更新的更改发布)但总的来说它工作得非常好!感谢帮助!
  • 将添加您的答案作为答案,但需要进行一些更改,因为更新的答案显示功能齐全(至少对于我的项目而言!)。
【解决方案2】:

这是 LazyRow 的替代版本,其中的项目也非常好用!

更新 2022.08.03

我创建了 2 个可组合项,1 个用于 LazyRow,1 个用于 Items 本身。我还添加了 flingbehaviour(第 3 方库,由 nglauber 建议),它允许它在屏幕中间捕捉,而无需在用户向左或向右滑动时“滚动”或“滑动”过去的项目!

结果如下: https://gyazo.com/53f38ed87002efb5676b20c4cd90d58f

将此添加到 build.gradle(app):

  // Dependency for the LazyRow from dev chrisBane - makes it "snap" in the middle of the screen
    implementation "dev.chrisbanes.snapper:snapper:0.2.2"

懒惰行:

@OptIn(ExperimentalSnapperApi::class, ExperimentalFoundationApi::class)
@Composable
fun LazyContainer() {

    val lazyListState = rememberLazyListState()

    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {

        LazyRow(
            state = lazyListState,
            flingBehavior = rememberSnapperFlingBehavior(lazyListState)

        ) {

            items(100, key = { it }) {

                ItemView(
                    title = it.toString(),
                    modifier = Modifier
                        .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                        .fillMaxWidth()
                     

                )

            }
        }
    }
}

在 LazyRow 中显示的项目:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ItemView(

modifier: Modifier = Modifier, 
title: String, 
selected: Boolean = false

) {
    Card(
        modifier = if (!selected) modifier
            .height(120.dp)
            .width(110.dp)
        else modifier
            .height(100.dp)
            .width(120.dp),
        shape = RoundedCornerShape(16.dp),
        elevation = if (selected) CardDefaults.cardElevation(24.dp) else CardDefaults.cardElevation(
            4.dp
        )
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {

            Text(
                text = title, modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center
            )
        }
    }
}

希望这有帮助!随意改进和修改它,快乐编码!

【讨论】:

    猜你喜欢
    • 2022-11-08
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多