Android Jetpack Compose 能够在每个项目上创建带有交互式按钮和值的列表吗?

Posted

技术标签:

【中文标题】Android Jetpack Compose 能够在每个项目上创建带有交互式按钮和值的列表吗?【英文标题】:Android Jetpack Compose capable of creating List with interactive Buttons and Values on each item? 【发布时间】:2021-11-04 09:59:05 【问题描述】:

我目前正在考虑为我的一个朋友创建一个主动跟踪应用程序,由于我已经有一段时间没有接触应用程序开发了,所以我正在尝试评估哪些工具最适合我的需求。

由于该应用程序将针对 android 开发,我很确定我将使用 Kotlin,因此 Jetpack Compose 引起了我的注意。 在进行了一些研究并浏览了文档之后,我不确定它是否能够实现我想要实现的目标: 我希望能够创建按分配给每张卡的特定值排序的入口卡的动态列表。 (我比较确定 LazyColumns 能够处理)。 问题是:每张卡片都需要有按钮和几个可以用这些按钮操作的附加值。 我无法在文档或任何使用 Jetpack Compose LazyColumns 的示例中找到此类内容的描述。

我创建了一个(制作糟糕的)模型,希望能更好地描述我想要做什么:

是否有人能够分享关于 Jetpack Compose 是否具备这些功能的见解,或者如果没有,可以分享关于改用什么工具的建议?

非常感谢和亲切的问候。

【问题讨论】:

【参考方案1】:

是的,使用 Compose,您可以非常轻松地制作这样的应用程序。

以下是此类 UI 的基本示例。

class MainActivity : FragmentActivity() 

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContent 
            AppTheme 
                ItemsScreen()
            
        
    


class Item(val title: String, value1: Int, value2: Int, value3: Int) 
    val value1 = mutableStateOf(value1)
    val value2 = mutableStateOf(value2)
    val value3 = mutableStateOf(value3)
    val valueToSortBy: Int
        get() = value1.value + value2.value + value3.value


class ScreenViewModel : ViewModel() 
    val items = List(3) 
        Item(
            "Item $it",
            Random.nextInt(10),
            Random.nextInt(10),
            Random.nextInt(10),
        )
    .toMutableStateList()

    fun sortItems() 
        items.sortByDescending  it.valueToSortBy 
    

    fun addNewItem() 
        items.add(
            Item(
                "Item $items.count()",
                Random.nextInt(10),
                Random.nextInt(10),
                Random.nextInt(10),
            )
        )
    


@Composable
fun ItemsScreen() 
    val viewModel: ScreenViewModel = viewModel()
    LaunchedEffect(viewModel.items.map  it.valueToSortBy ) 
        viewModel.sortItems()
    
    Box(
        Modifier
            .fillMaxSize()
            .padding(10.dp)
    ) 
        LazyColumn(
            contentPadding = PaddingValues(vertical = 10.dp),
            verticalArrangement = Arrangement.spacedBy(10.dp)
        ) 
            items(viewModel.items)  item ->
                ItemView(item)
            
        
        FloatingActionButton(
            onClick = viewModel::addNewItem,
            modifier = Modifier.align(Alignment.BottomEnd)
        ) 
            Text("+")
        
    


@Composable
fun ItemView(item: Item) 
    Card(
        elevation = 5.dp,
    ) 
        Column(modifier = Modifier.padding(10.dp)) 
            Row(
                verticalAlignment = Alignment.CenterVertically,
            ) 
                Text(
                    item.title,
                    style = MaterialTheme.typography.h5
                )
                Spacer(modifier = Modifier.weight(1f))
                Text(
                    "Value to sort by: $item.valueToSortBy",
                    style = MaterialTheme.typography.body1,
                    fontStyle = FontStyle.Italic,
                )
            
            Spacer(modifier = Modifier.size(25.dp))
            Row(
                horizontalArrangement = Arrangement.SpaceBetween,
                modifier = Modifier.fillMaxWidth()
            ) 
                CounterView(value = item.value1.value, setValue =  item.value1.value = it )
                CounterView(value = item.value2.value, setValue =  item.value2.value = it )
                CounterView(value = item.value3.value, setValue =  item.value3.value = it )
            
        
    


@Composable
fun CounterView(value: Int, setValue: (Int) -> Unit) 
    Row(verticalAlignment = Alignment.CenterVertically) 
        CounterButton("+") 
            setValue(value + 1)
        
        Text(
            value.toString(),
            modifier = Modifier.padding(5.dp)
        )
        CounterButton("-") 
            setValue(value - 1)
        
    


@Composable
fun CounterButton(text: String, onClick: () -> Unit) 
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .size(45.dp)
            .background(Color.LightGray)
            .clickable(onClick = onClick)
    ) 
        Text(
            text,
            color = Color.White,
        )
    

我在这里按 3 个值的总和进行排序。请注意,像这样对项目进行排序在生产应用程序中可能没有太大的性能,您应该使用数据库来存储项目并从中请求排序的项目。

【讨论】:

非常感谢您提供广泛而详细的回答。至于数据库,是的,我打算使用 sqlite 或类似的轻量级数据库来处理数据。 @Thormgrim 你可以在SQLDelight 上查看,它非常简单,所有数据库的工作都是通过 SQL 完成的,为你创建的所有 SQL 函数提供了一个不错的 kotlin API 我似乎无法像您发布的 gif 那样运行它。对我来说它非常紧张,这可能是因为我更改了 AppTheme 类和 val viewModel: ScreenViewModel = viewModel() 因为这些无法解决。这些来自哪里的任何建议? @Thormgrim 更改 AppTheme 很好,但您不应该更改 viewModel()。确保你有import androidx.lifecycle.viewmodel.compose.viewModel,如果这没有帮助,请告诉我确切的错误 感谢您的快速响应。尽管您提到的导入似乎无法为我解决,但您是否为此使用了任何特定的依赖项?

以上是关于Android Jetpack Compose 能够在每个项目上创建带有交互式按钮和值的列表吗?的主要内容,如果未能解决你的问题,请参考以下文章

Android全新UI编程 - Jetpack Compose 超详细教程

Compose能拯救安卓开发吗?Jetpack Compose入门到精通(附资料)含实战附Demo

作为一名Android开发人员,怎么能不快速掌握互联网热门技术!开经络,识秘籍:《Jetpack Compose + 鸿蒙入门指南》

Android Jetpack Compose学习—— Jetpack compose基础布局

Android Jetpack Compose学习—— Jetpack compose基础布局

Android Jetpack Compose学习—— Jetpack compose基础布局