Android compose测试数据双向绑定

之前测试过dataBinding绑定数据,再试下compose绑定数据。

Kotlin 复制代码
package com.example.testcompose1

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            todoJobList()
        }
    }
}

@Preview
@Composable
fun todoJobList() { // 显示待办事项
    val context = LocalContext.current

    // 使用 remember 和 mutableStateOf 保存输入框的文本
    var text by remember { mutableStateOf("") }
    // 使用 mutableStateListOf 保存待办项列表
    val todoItems = remember { mutableStateListOf<String>() }

    Column(modifier = Modifier.padding(16.dp)) {
        // 文本输入框
        TextField(
            value = text,
            onValueChange = { text = it }, // 反向绑定,视图变化--> 数据变化
            label = { Text("输入待办事项") },
            modifier = Modifier.fillMaxWidth()
        )
        // 添加按钮
        Button(
            onClick = {
                if (text.isNotBlank()) {
                    println("添加:$text")
                    Toast.makeText(context, "添加:$text", Toast.LENGTH_SHORT).show()
                    todoItems.add(text)  // 添加到列表
                    text = ""            // 清空输入. 测试正向绑定,数据状态变化--> 视图变化
                }
            },
            modifier = Modifier.padding(top = 8.dp)
        ) {
            Text("添加")
        }

        // 显示待办列表
        Spacer(modifier = Modifier.height(16.dp))
        Text("待办列表", style = MaterialTheme.typography.titleMedium)
        LazyColumn {
            items(items = todoItems) { item ->
                TodoItem(item = item)
            }
        }
    }
}

@Composable
fun TodoItem(item: String) {
    Text(
        text = item,
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp)
    )
}

运行:

可以随便输入点什么点击添加,会添加到下面的列表中:

ok. mutableStateOf能创建可观察状态的数据,值变化的时候重组刷新页面。remember能让状态重组时记住之前的值,不被重置。

每一条数据旁再添加个删除按钮。

修改下TodoItem函数,增加一个删除按钮,删除函数由onDelete参数传入:

Kotlin 复制代码
@Composable
fun TodoItem(item: String, onDelete: () -> Unit  // 添加删除回调,删除逻辑放在上层。即把回调传给里面的按钮。
 ) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween // 横向布局子元素两端对齐,剩余空白空间平均分配到子元素之间
    ) {
        Text(text = item)
        IconButton(onClick = onDelete) {
            Icon(Icons.Default.Delete, contentDescription = "删除")
        }
    }
}

再修改下todoJoblist函数,将删除函数传给子组件:

修改完完整代码:

Kotlin 复制代码
package com.example.testcompose1

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            todoJobList()
        }
    }
}

@Preview
@Composable
fun todoJobList() {
    val context = LocalContext.current

    // 使用 remember 和 mutableStateOf 保存输入框的文本
    var text by remember { mutableStateOf("") }
    // 使用 mutableStateListOf 保存待办项列表
    val todoItems = remember { mutableStateListOf<String>() }

    Column(modifier = Modifier.padding(16.dp)) {
        // 文本输入框
        TextField(
            value = text,
            onValueChange = { text = it }, // 反向绑定,视图变化--> 数据变化
            label = { Text("输入待办事项") },
            modifier = Modifier.fillMaxWidth()
        )
        // 添加按钮
        Button(
            onClick = {
                if (text.isNotBlank()) {
                    println("添加:$text")
                    Toast.makeText(context, "添加:$text", Toast.LENGTH_SHORT).show()
                    todoItems.add(text)  // 添加到列表
                    text = ""            // 清空输入. 测试正向绑定,数据状态变化--> 视图变化
                }
            },
            modifier = Modifier.padding(top = 8.dp)
        ) {
            Text("添加")
        }

        // 显示待办列表
        Spacer(modifier = Modifier.height(16.dp))
        Text("待办列表", style = MaterialTheme.typography.titleMedium)
        LazyColumn {
            items(items = todoItems) { item ->
                TodoItem(item = item
                    , onDelete = { todoItems.remove(item) })  // 点击时从列表中删除
            }
        }
    }
}

@Composable
fun TodoItem(item: String, onDelete: () -> Unit  // 添加删除回调,删除逻辑放在上层。即把回调传给里面的按钮。
 ) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween // 横向布局子元素两端对齐,剩余空白空间平均分配到子元素之间
    ) {
        Text(text = item)
        IconButton(onClick = onDelete) {
            Icon(Icons.Default.Delete, contentDescription = "删除")
        }
    }
}

测试下,添加几条数据:

删除一个:

ok. 状态管理没问题。

相关推荐
alexhilton5 小时前
Kotlin DSL深度解析:从Gradle脚本到构建你自己的DSL
android·kotlin·android jetpack
烽火聊员5 小时前
查看Android Studio错误日志
android·ide·android studio
星空语10 小时前
音频001_Android+Linux车载/手机音频全链路分层架构图
android·linux·音视频
CyL_Cly11 小时前
解决官网下载慢!Android Studio 最新版网盘下载
android·ide·android studio
智塑未来11 小时前
鸿蒙系统对比安卓、iOS,核心优势是什么?
android·ios·harmonyos
AI刀刀11 小时前
豆包智能体对话导出后,如何构建长期归档与高效检索体系?
android·人工智能·word·excel·ai导出鸭
初雪云13 小时前
iOS 上架入门:证书、描述文件、IPA 上传到底是什么关系?
android·ios·自动化·产品经理·iphone
玩机达人8815 小时前
一加12/Ace5/Ace3pro手机ColorOS16降级回锁BL熔断变黑砖怎么办
android·智能手机·电脑
Digitally16 小时前
使用 USB 数据线将文件从安卓设备传输到电脑
android·电脑
xieliyu.17 小时前
MySQL 六大基础约束详解:NOT NULL/DEFAULT/UNIQUE/ 主键 / 外键 / CHECK
android·数据库·sql·mysql