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. 状态管理没问题。

相关推荐
liang_jy4 小时前
Android View Tag
android
liang_jy5 小时前
Android 架构中的统一分发与策略路由
android·架构
scan7247 小时前
长期记忆存储在数据库里
android
xingpanvip7 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
儿歌八万首9 小时前
Jetpack Compose 实战:实现一个动态平滑折线图
android·折线图·compose
李艺为13 小时前
Fake Device Test作假屏幕分辨率分析
android·java
zh_xuan13 小时前
github远程library仓库升级
android·github
峥嵘life14 小时前
Android蓝牙停用绝对音量原理
android
czlczl2002092515 小时前
IN和BETWEEN在索引效能的区别
android·adb
Volunteer Technology15 小时前
ES高级搜索功能
android·大数据·elasticsearch