状态
单状态
状态是声明式UI中最重要的概念。当状态值发生改变时,UI会根据需要自动更新,无需像命令式UI那样通过代码手动更新UI。你只需改变状态值,例如按钮点击时:
声明式UI中只需改变状态值,如
state.setValue(state.getValue() + 1)(每点击一次自增1)。当状态改变时,所有通过trackSingleState添加该状态的Composable都会自动更新,无需手动操作。命令式UI中需要直接修改控件属性,如
textView.setText(textView.getText().toInt() + 1)。若存在多个关联组件,还需逐一修改,例如textView2.setText(textView2.getText().toInt() + 1)。
import com.m8test.script.GlobalVariables.*
fun side1Run() {
// 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create {
// 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
// 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
Column {
// 设置 Column 中 content 插槽的内容
setContent {
// 1. 创建一个可变状态,用于保存计数器的值
val count = mutableStateOf(0)
// 添加一个文件组件到 Column (垂直布局)中
Text {
// 2. 在组件的某个属性中使用该状态的值
setText(count.getValue().toString())
// 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
trackSingleState(count)
}
// 添加一个文本按钮到 Column (垂直布局)中
TextButton {
// 设置文本按钮的content插槽内容
setContent {
// 在插槽中添加一个文本
Text {
setText("点击我")
}
}
// 设置按钮点击事件
setOnClick {
// 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count.setValue(count.getValue() + 1)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
_activity.start()
}
// 下面的语句中的 '//-m8test-remove' 在实际编译时会被删除,也就是将会改成 'side1Run();', 但是不能省略,否则 side1Run 方法不会被执行
//-m8test-remove side1Run();
// 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create { slot ->
// 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
// 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
slot.Column { column ->
// 设置 Column 中 content 插槽的内容
column.setContent { columnSlot ->
// 1. 创建一个可变状态,用于保存计数器的值
def count = columnSlot.mutableStateOf(0)
// 添加一个文件组件到 Column (垂直布局)中
columnSlot.Text { text ->
// 2. 在组件的某个属性中使用该状态的值
text.setText(count.getValue().toString())
// 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
text.trackSingleState(count)
}
// 添加一个文本按钮到 Column (垂直布局)中
columnSlot.TextButton { button ->
// 设置文本按钮的content插槽内容
button.setContent { buttonSlot ->
// 在插槽中添加一个文本
buttonSlot.Text { text ->
text.setText("点击我")
}
}
// 设置按钮点击事件
button.setOnClick {
// 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count.setValue(count.getValue() + 1)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
$activity.start()
// 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create(slot => {
// 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
// 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
slot.Column(column => {
// 设置 Column 中 content 插槽的内容
column.setContent(columnSlot => {
// 1. 创建一个可变状态,用于保存计数器的值
const count = columnSlot.mutableStateOf(0);
// 添加一个文件组件到 Column (垂直布局)中
columnSlot.Text(text => {
// 2. 在组件的某个属性中使用该状态的值
text.setText(count.getValue().toString());
// 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
text.trackSingleState(count);
});
// 添加一个文本按钮到 Column (垂直布局)中
columnSlot.TextButton(button => {
// 设置文本按钮的content插槽内容
button.setContent(buttonSlot => {
// 在插槽中添加一个文本
buttonSlot.Text(text => {
text.setText("点击我");
});
});
// 设置按钮点击事件
button.setOnClick(() => {
// 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count.setValue(count.getValue() + 1);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity.start();
-- 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
-- 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView:create(function(slot)
-- 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
-- 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
slot:Column(function(column)
-- 设置 Column 中 content 插槽的内容
column:setContent(function(columnSlot)
-- 1. 创建一个可变状态,用于保存计数器的值
local count = columnSlot:mutableStateOf(0)
-- 添加一个文件组件到 Column (垂直布局)中
columnSlot:Text(function(text)
-- 2. 在组件的某个属性中使用该状态的值
text:setText(tostring(count:getValue()))
-- 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
text:trackSingleState(count)
end)
-- 添加一个文本按钮到 Column (垂直布局)中
columnSlot:TextButton(function(button)
-- 设置文本按钮的content插槽内容
button:setContent(function(buttonSlot)
-- 在插槽中添加一个文本
buttonSlot:Text(function(text)
text:setText("点击我")
end)
end)
-- 设置按钮点击事件
button:setOnClick(function()
-- 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count:setValue(count:getValue() + 1)
end)
end)
end)
end)
end)
-- 启动一个Activity用于显示脚本界面
_activity:start()
<?php
/** @var m8test_java\com\m8test\script\core\api\ui\compose\ComposeView $composeView */
global $composeView;
/** @var m8test_java\com\m8test\script\core\api\ui\Activity $activity */
global $activity;
// 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView->create(function ($slot) {
// 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
// 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
$slot->Column(function ($column) {
// 设置 Column 中 content 插槽的内容
$column->setContent(function ($columnSlot) {
// 1. 创建一个可变状态,用于保存计数器的值
$count = $columnSlot->mutableStateOf(0);
// 添加一个文件组件到 Column (垂直布局)中
$columnSlot->Text(function ($text) use ($count) {
// 2. 在组件的某个属性中使用该状态的值 (将数字转换为字符串)
$text->setText((string)$count->getValue());
// 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
$text->trackSingleState($count);
});
// 添加一个文本按钮到 Column (垂直布局)中
$columnSlot->TextButton(function ($button) use ($count) {
// 设置文本按钮的content插槽内容
$button->setContent(function ($buttonSlot) {
// 在插槽中添加一个文本
$buttonSlot->Text(function ($text) {
$text->setText(javaString("点击我"));
});
});
// 设置按钮点击事件
$button->setOnClick(function () use ($count) {
// 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
$count->setValue($count->getValue() + 1);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity->start();
# 导入所需的全局变量,每一行导入一个
from m8test_java.com.m8test.script.GlobalVariables import _activity
from m8test_java.com.m8test.script.GlobalVariables import _composeView
# 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create(lambda slot:
# 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
# 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
slot.Column(lambda column:
# 设置 Column 中 content 插槽的内容
column.setContent(lambda columnSlot: (
# 1. 创建一个可变状态,用于保存计数器的值
# 使用海象运算符 `:=` 在表达式内部进行赋值
(count := columnSlot.mutableStateOf(0)),
# 添加一个文件组件到 Column (垂直布局)中
# 因为 lambda 中需要执行多个操作,所以我们把它们放到一个元组里
columnSlot.Text(lambda text: (
# 2. 在组件的某个属性中使用该状态的值
# Groovy 的 .toString() 相当于 Python 的 str()
text.setText(str(count.getValue())),
# 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
text.trackSingleState(count)
)),
# 添加一个文本按钮到 Column (垂直布局)中
columnSlot.TextButton(lambda button: (
# 设置文本按钮的content插槽内容
button.setContent(lambda buttonSlot:
# 在插槽中添加一个文本
buttonSlot.Text(lambda text:
text.setText("点击我")
)
),
# 设置按钮点击事件
button.setOnClick(lambda:
# 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count.setValue(count.getValue() + 1)
)
))
))
)
)
# 启动一个Activity用于显示脚本界面
_activity.start()
# encoding: utf-8
# 这是一个非常简单的例子,当点击按钮时会将计数器(状态)的值加1,状态改变后,使用到该状态的文本会自动更新
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create do |slot|
# 插槽(Slot)是一种内容分发机制。它允许你在封装一个通用组件时,在组件内部预留一些“坑位”或“插槽”,然后让使用该组件的父组件来决定这些“坑位”里到底填充什么内容。
# 创建一个Column,Column是一种垂直布局,可以让其中的组件垂直排列
slot.Column do |column|
# 设置 Column 中 content 插槽的内容
column.setContent do |columnSlot|
# 1. 创建一个可变状态,用于保存计数器的值
count = columnSlot.mutableStateOf(0)
# 添加一个文件组件到 Column (垂直布局)中
columnSlot.Text do |text|
# 2. 在组件的某个属性中使用该状态的值
text.setText(count.getValue().to_s)
# 3. 将状态添加到组件中,这样text组件就会监听该状态的改变,这个是必须的步骤,如果没有此步骤,那么 count 的值改变时,composable(text组件)不会重组(界面更新)
text.trackSingleState(count)
end
# 添加一个文本按钮到 Column (垂直布局)中
columnSlot.TextButton do |button|
# 设置文本按钮的content插槽内容
button.setContent do |buttonSlot|
# 在插槽中添加一个文本
buttonSlot.Text do |text|
text.setText("点击我")
end
end
# 设置按钮点击事件
button.setOnClick do
# 4. 当按钮被点击时,更新状态的值,这时使用到count的所有组件都会重组(界面更新), 必须要 trackSingleState
count.setValue(count.getValue() + 1)
end
end
end
end
end
# 启动一个Activity用于显示脚本界面
$activity.start()
对于状态列表,可通过 LazyRow 或 LazyColumn 实现。当列表中的元素发生改变时, LazyRow 或 LazyColumn 会自动更新。
import com.m8test.script.GlobalVariables.*
fun side1Run() {
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create {
// 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
val state = mutableStateListOf(_iterables.listOf("初始数据"))
LazyColumn {
setModifier { fillMaxWidth(1f) }
// 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
trackSingleState(state)
// 设置懒列表内容
setContent {
// 设置列表固定头
stickyHeader(null, null) { index ->
// 添加一个 Button 到列表固定头
Button {
// 设置按钮内容
setContent {
// 添加文本到按钮中
Text {
// 设置按钮中文本显示的内容
setText("添加项目")
}
}
// 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
setOnClick { state.add("+++++") }
}
}
// 3. 将状态列表中的数据显示到 LazyColumn 中
itemsIndexed(state, null, null) { index, item ->
// 状态列表中每个元素显示一个简单的 Text 组件
Text {
setModifier {
height { d -> d.fromInt(200) }
}
// 设置 Text 组件显示的内容
setText(item)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
_activity.start()
}
//-m8test-remove side1Run();
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create { slot ->
// 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
def state = slot.mutableStateListOf($iterables.listOf("初始数据"))
slot.LazyColumn { lc ->
lc.setModifier { it.fillMaxWidth(1f) }
// 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state)
// 设置懒列表内容
lc.setContent { lls ->
// 设置列表固定头
lls.stickyHeader(null, null) { llss, index ->
// 添加一个 Button 到列表固定头
llss.Button { button ->
// 设置按钮内容
button.setContent { bs ->
// 添加文本到按钮中
bs.Text { text ->
// 设置按钮中文本显示的内容
text.setText("添加项目")
}
}
// 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick { state.add("+++++") }
}
}
// 3. 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, null, null) { llss, index, item ->
// 状态列表中每个元素显示一个简单的 Text 组件
llss.Text { text ->
text.setModifier {
it.height { d -> d.fromInt(200) }
}
// 设置 Text 组件显示的内容
text.setText(item)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
$activity.start()
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create(slot => {
// 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
const state = slot.mutableStateListOf($iterables.listOf("初始数据"));
slot.LazyColumn(lc => {
lc.setModifier(it => it.fillMaxWidth(1.0));
// 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state);
// 设置懒列表内容
lc.setContent(lls => {
// 设置列表固定头
lls.stickyHeader(null, null, (llss, index) => {
// 添加一个 Button 到列表固定头
llss.Button(button => {
// 设置按钮内容
button.setContent(bs => {
// 添加文本到按钮中
bs.Text(text => {
// 设置按钮中文本显示的内容
text.setText("添加项目");
});
});
// 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick(() => state.add("+++++"));
});
});
// 3. 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, null, null, (llss, index, item) => {
// 状态列表中每个元素显示一个简单的 Text 组件
llss.Text(text => {
text.setModifier(it => {
it.height(d => d.fromInt(200));
});
// 设置 Text 组件显示的内容
text.setText(item);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity.start();
-- 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView:create(function(slot)
-- 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
local state = slot:mutableStateListOf(_iterables:listOf("初始数据"))
slot:LazyColumn(function(lc)
lc:setModifier(function(it)
it:fillMaxWidth(1)
end)
-- 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc:trackSingleState(state)
-- 设置懒列表内容
lc:setContent(function(lls)
-- 设置列表固定头
lls:stickyHeader(nil, nil, function(llss, index)
-- 添加一个 Button 到列表固定头
llss:Button(function(button)
-- 设置按钮内容
button:setContent(function(bs)
-- 添加文本到按钮中
bs:Text(function(text)
-- 设置按钮中文本显示的内容
text:setText("添加项目")
end)
end)
-- 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button:setOnClick(function()
state:add("+++++")
end)
end)
end)
-- 3. 将状态列表中的数据显示到 LazyColumn 中
lls:itemsIndexed(state, nil, nil, function(llss, index, item)
-- 状态列表中每个元素显示一个简单的 Text 组件
llss:Text(function(text)
text:setModifier(function(it)
it:height(function(d) return d:fromInt(200) end)
end)
-- 设置 Text 组件显示的内容
text:setText(item)
end)
end)
end)
end)
end)
-- 启动一个Activity用于显示脚本界面
_activity:start()
<?php
/** @var m8test_java\com\m8test\script\core\api\ui\compose\ComposeView $composeView */
global $composeView;
/** @var m8test_java\com\m8test\script\core\api\ui\Activity $activity */
global $activity;
/** @var m8test_java\com\m8test\script\core\api\collections\Iterables $iterables */
global $iterables;
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView->create(function ($slot) {
global $iterables;
// 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
$state = $slot->mutableStateListOf($iterables->listOf(javaString("初始数据")));
$slot->LazyColumn(function ($lc) use ($state) {
$lc->setModifier(function ($it) {
$it->fillMaxWidth(1.0);
});
// 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
$lc->trackSingleState($state);
// 设置懒列表内容
$lc->setContent(function ($lls) use ($state) {
// 设置列表固定头
$lls->stickyHeader(null, null, function ($llss, $index) use ($state) {
// 添加一个 Button 到列表固定头
$llss->Button(function ($button) use ($state) {
// 设置按钮内容
$button->setContent(function ($bs) {
// 添加文本到按钮中
$bs->Text(function ($text) {
// 设置按钮中文本显示的内容
$text->setText(javaString("添加项目"));
});
});
// 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
$button->setOnClick(function () use ($state) {
$state->add(javaString("+++++"));
});
});
});
// 3. 将状态列表中的数据显示到 LazyColumn 中
$lls->itemsIndexed($state, null, null, function ($llss, $index, $item) {
// 状态列表中每个元素显示一个简单的 Text 组件
$llss->Text(function ($text) use ($item) {
$text->setModifier(function ($it) {
$it->height(function ($d) {
return $d->fromInt(200);
});
});
// 设置 Text 组件显示的内容
$text->setText($item);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity->start();
# 导入所需的全局变量
from m8test_java.com.m8test.script.GlobalVariables import _activity
from m8test_java.com.m8test.script.GlobalVariables import _composeView
from m8test_java.com.m8test.script.GlobalVariables import _iterables
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create(lambda slot: (
# 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
(state := slot.mutableStateListOf(_iterables.listOf("初始数据"))),
slot.LazyColumn(lambda lc: (
lc.setModifier(lambda it: it.fillMaxWidth(1.0)),
# 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state),
# 设置懒列表内容
lc.setContent(lambda lls: (
# 设置列表固定头
lls.stickyHeader(None, None, lambda llss, index: (
# 添加一个 Button 到列表固定头
llss.Button(lambda button: (
# 设置按钮内容
button.setContent(lambda bs: (
# 添加文本到按钮中
bs.Text(lambda text: (
# 设置按钮中文本显示的内容
text.setText("添加项目")
))
)),
# 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick(lambda: state.add("+++++"))
))
)),
# 3. 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, None, None, lambda llss, index, item: (
# 状态列表中每个元素显示一个简单的 Text 组件
llss.Text(lambda text: (
text.setModifier(lambda it: (
it.height(lambda d: d.fromInt(200))
)),
# 设置 Text 组件显示的内容
text.setText(item)
))
))
))
))
))
# 启动一个Activity用于显示脚本界面
_activity.start()
# encoding: utf-8
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create do |slot|
# 1. 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
state = slot.mutableStateListOf($iterables.listOf("初始数据"))
slot.LazyColumn do |lc|
lc.setModifier { |it| it.fillMaxWidth(1.0) }
# 2. 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state)
# 设置懒列表内容
lc.setContent do |lls|
# 设置列表固定头
lls.stickyHeader(nil, nil) do |llss, index|
# 添加一个 Button 到列表固定头
llss.Button do |button|
# 设置按钮内容
button.setContent do |bs|
# 添加文本到按钮中
bs.Text do |text|
# 设置按钮中文本显示的内容
text.setText("添加项目")
end
end
# 4. 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick { state.add("+++++") }
end
end
# 3. 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, nil, nil) do |llss, index, item|
# 状态列表中每个元素显示一个简单的 Text 组件
llss.Text do |text|
text.setModifier do |it|
it.height { |d| d.fromInt(200) }
end
# 设置 Text 组件显示的内容
text.setText(item)
end
end
end
end
end
# 启动一个Activity用于显示脚本界面
$activity.start()
聚合状态
有些组件包含多个状态,M8Test 将其封装为聚合状态。你可以通过聚合状态对象修改所需的状态,例如:
import com.m8test.script.GlobalVariables.*
fun side1Run() {
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create {
// 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
val state = mutableStateListOf(_iterables.listOf("初始数据"))
// 1. 创建一个懒列表状态,用于控制 LazyColumn
val lazyState = newLazyListState {}
LazyColumn {
setModifier { fillMaxWidth(1f) }
// 2. 设置懒列表的状态
setState(lazyState)
// 跟踪状态列表,当列表增删改时 LazyColumn 会重组
trackSingleState(state)
// 设置懒列表内容
setContent {
// 设置列表固定头
stickyHeader(null, null) { index ->
// 添加一个 Button 到列表固定头
Button {
// 设置按钮内容
setContent {
// 添加文本到按钮中
Text {
// trackAggregatedState(lazyState) // 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
trackSingleState(lazyState.getFirstVisibleItemIndexState()) // 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
// 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
setText("添加项目${lazyState.getFirstVisibleItemIndexState().getValue()}")
}
}
// 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
setOnClick { state.add("+++++") }
}
}
// 将状态列表中的数据显示到 LazyColumn 中
itemsIndexed(state, null, null) { index, item ->
// 状态列表中每个元素显示一个简单的 Text 组件
Text {
setModifier {
height { d -> d.fromInt(200) }
}
// 设置 Text 组件显示的内容
setText(item)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
_activity.start()
}
//-m8test-remove side1Run();
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create { slot ->
// 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
def state = slot.mutableStateListOf($iterables.listOf("初始数据"))
// 1. 创建一个懒列表状态,用于控制 LazyColumn
def lazyState = slot.newLazyListState {}
slot.LazyColumn { lc ->
lc.setModifier { it.fillMaxWidth(1f) }
// 2. 设置懒列表的状态
lc.setState(lazyState)
// 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state)
// 设置懒列表内容
lc.setContent { lls ->
// 设置列表固定头
lls.stickyHeader(null, null) { llss, index ->
// 添加一个 Button 到列表固定头
llss.Button { button ->
// 设置按钮内容
button.setContent { bs ->
// 添加文本到按钮中
bs.Text { text ->
// text.trackAggregatedState(lazyState) // 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
text.trackSingleState(lazyState.getFirstVisibleItemIndexState()) // 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
// 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
text.setText("添加项目" + lazyState.getFirstVisibleItemIndexState().getValue())
}
}
// 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick { state.add("+++++") }
}
}
// 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, null, null) { llss, index, item ->
// 状态列表中每个元素显示一个简单的 Text 组件
llss.Text { text ->
text.setModifier {
it.height { d -> d.fromInt(200) }
}
// 设置 Text 组件显示的内容
text.setText(item)
}
}
}
}
}
// 启动一个Activity用于显示脚本界面
$activity.start()
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create(slot => {
// 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
const state = slot.mutableStateListOf($iterables.listOf("初始数据"));
// 1. 创建一个懒列表状态,用于控制 LazyColumn
const lazyState = slot.newLazyListState(() => {});
slot.LazyColumn(lc => {
lc.setModifier(it => it.fillMaxWidth(1));
// 2. 设置懒列表的状态
lc.setState(lazyState);
// 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state);
// 设置懒列表内容
lc.setContent(lls => {
// 设置列表固定头
lls.stickyHeader(null, null, (llss, index) => {
// 添加一个 Button 到列表固定头
llss.Button(button => {
// 设置按钮内容
button.setContent(bs => {
// 添加文本到按钮中
bs.Text(text => {
// text.trackAggregatedState(lazyState) // 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
text.trackSingleState(lazyState.getFirstVisibleItemIndexState()); // 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
// 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
text.setText("添加项目" + lazyState.getFirstVisibleItemIndexState().getValue());
});
});
// 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick(() => state.add("+++++"));
});
});
// 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, null, null, (llss, index, item) => {
// 状态列表中每个元素显示一个简单的 Text 组件
llss.Text(text => {
text.setModifier(it => {
it.height(d => d.fromInt(200));
});
// 设置 Text 组件显示的内容
text.setText(item);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity.start();
-- 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView:create(function(slot)
-- 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
local state = slot:mutableStateListOf(_iterables:listOf("初始数据"))
-- 1. 创建一个懒列表状态,用于控制 LazyColumn
local lazyState = slot:newLazyListState(function() end)
slot:LazyColumn(function(lc)
lc:setModifier(function(it) return it:fillMaxWidth(1.0) end)
-- 2. 设置懒列表的状态
lc:setState(lazyState)
-- 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc:trackSingleState(state)
-- 设置懒列表内容
lc:setContent(function(lls)
-- 设置列表固定头
lls:stickyHeader(nil, nil, function(llss, index)
-- 添加一个 Button 到列表固定头
llss:Button(function(button)
-- 设置按钮内容
button:setContent(function(bs)
-- 添加文本到按钮中
bs:Text(function(text)
-- text:trackAggregatedState(lazyState) -- 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
text:trackSingleState(lazyState:getFirstVisibleItemIndexState()) -- 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
-- 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
text:setText("添加项目" .. tostring(lazyState:getFirstVisibleItemIndexState():getValue()))
end)
end)
-- 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button:setOnClick(function() state:add("+++++") end)
end)
end)
-- 将状态列表中的数据显示到 LazyColumn 中
lls:itemsIndexed(state, nil, nil, function(llss, index, item)
-- 状态列表中每个元素显示一个简单的 Text 组件
llss:Text(function(text)
text:setModifier(function(it)
return it:height(function(d) return d:fromInt(200) end)
end)
-- 设置 Text 组件显示的内容
text:setText(item)
end)
end)
end)
end)
end)
-- 启动一个Activity用于显示脚本界面
_activity:start()
<?php
/** @var m8test_java\com\m8test\script\core\api\ui\compose\ComposeView $composeView */
global $composeView;
/** @var m8test_java\com\m8test\script\core\api\ui\Activity $activity */
global $activity;
/** @var m8test_java\com\m8test\script\core\api\collections\Iterables $iterables */
global $iterables;
// 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView->create(function ($slot) {
global $iterables;
// 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
$state = $slot->mutableStateListOf($iterables->listOf(javaString("初始数据")));
// 1. 创建一个懒列表状态,用于控制 LazyColumn
$lazyState = $slot->newLazyListState(function () {
});
$slot->LazyColumn(function ($lc) use ($lazyState, $state) {
$lc->setModifier(function ($it) {
$it->fillMaxWidth(1.0);
});
// 2. 设置懒列表的状态
$lc->setState($lazyState);
// 跟踪状态列表,当列表增删改时 LazyColumn 会重组
$lc->trackSingleState($state);
// 设置懒列表内容
$lc->setContent(function ($lls) use ($lazyState, $state) {
// 设置列表固定头
$lls->stickyHeader(null, null, function ($llss, $index) use ($lazyState, $state) {
// 添加一个 Button 到列表固定头
$llss->Button(function ($button) use ($lazyState, $state) {
// 设置按钮内容
$button->setContent(function ($bs) use ($lazyState) {
// 添加文本到按钮中
$bs->Text(function ($text) use ($lazyState) {
// $text->trackAggregatedState($lazyState); // 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
$text->trackSingleState($lazyState->getFirstVisibleItemIndexState()); // 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
// 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
$text->setText(javaString("添加项目") . $lazyState->getFirstVisibleItemIndexState()->getValue());
});
});
// 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
$button->setOnClick(function () use ($state) {
$state->add(javaString("+++++"));
});
});
});
// 将状态列表中的数据显示到 LazyColumn 中
$lls->itemsIndexed($state, null, null, function ($llss, $index, $item) {
// 状态列表中每个元素显示一个简单的 Text 组件
$llss->Text(function ($text) use ($item) {
$text->setModifier(function ($it) {
$it->height(function ($d) {
return $d->fromInt(200);
});
});
// 设置 Text 组件显示的内容
$text->setText($item);
});
});
});
});
});
// 启动一个Activity用于显示脚本界面
$activity->start();
# 导入所需的全局变量
from m8test_java.com.m8test.script.GlobalVariables import _composeView
from m8test_java.com.m8test.script.GlobalVariables import _iterables
from m8test_java.com.m8test.script.GlobalVariables import _activity
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
_composeView.create(lambda slot: (
# 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
(state := slot.mutableStateListOf(_iterables.listOf("初始数据"))),
# 1. 创建一个懒列表状态,用于控制 LazyColumn
# [修复] 这里的lambda需要接收一个参数但可以忽略它
(lazyState := slot.newLazyListState(lambda _: None)),
slot.LazyColumn(lambda lc: (
lc.setModifier(lambda it: it.fillMaxWidth(1.0)),
# 2. 设置懒列表的状态
lc.setState(lazyState),
# 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state),
# 设置懒列表内容
lc.setContent(lambda lls: (
# 设置列表固定头
lls.stickyHeader(None, None, lambda llss, index: (
# 添加一个 Button 到列表固定头
llss.Button(lambda button: (
# 设置按钮内容
button.setContent(lambda bs: (
# 添加文本到按钮中
bs.Text(lambda text: (
# text.trackAggregatedState(lazyState) # 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
text.trackSingleState(lazyState.getFirstVisibleItemIndexState()), # 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
# 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
text.setText("添加项目" + str(lazyState.getFirstVisibleItemIndexState().getValue()))
))
)),
# 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick(lambda: state.add("+++++"))
))
)),
# 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, None, None, lambda llss, index, item: (
# 状态列表中每个元素显示一个简单的 Text 组件
llss.Text(lambda text: (
text.setModifier(lambda it: (
it.height(lambda d: d.fromInt(200))
)),
# 设置 Text 组件显示的内容
text.setText(item)
))
))
))
))
))
# 启动一个Activity用于显示脚本界面
_activity.start()
# encoding: utf-8
# 创建一个 ComposeView, 可以通过声明式ui创建脚本界面
$composeView.create do |slot|
# 创建一个状态列表,向 LazyColumn 提供数据,当其中的元素发生改变(增删改)时,用到该状态列表的组件会重组
state = slot.mutableStateListOf($iterables.listOf("初始数据"))
# 1. 创建一个懒列表状态,用于控制 LazyColumn
lazyState = slot.newLazyListState {}
slot.LazyColumn do |lc|
lc.setModifier { |it| it.fillMaxWidth(1.0) }
# 2. 设置懒列表的状态
lc.setState(lazyState)
# 跟踪状态列表,当列表增删改时 LazyColumn 会重组
lc.trackSingleState(state)
# 设置懒列表内容
lc.setContent do |lls|
# 设置列表固定头
lls.stickyHeader(nil, nil) do |llss, index|
# 添加一个 Button 到列表固定头
llss.Button do |button|
# 设置按钮内容
button.setContent do |bs|
# 添加文本到按钮中
bs.Text do |text|
# text.trackAggregatedState(lazyState) // 这个代码会跟踪 lazyState 中所有的状态, 当任意一个状态发生改变时 Text 都会重组
text.trackSingleState(lazyState.getFirstVisibleItemIndexState()) # 3. 这个代码仅仅会跟踪 lazyState 的第一个可见项目索引, 当该状态发生改变时 Text 会重组, 推荐使用这种方式, 只跟踪用到的状态
# 4. 使用跟踪的状态值,如果该状态发生改变,那么 Text 文本会更新
text.setText("添加项目" + lazyState.getFirstVisibleItemIndexState().getValue().to_s)
end
end
# 设置按钮点击事件,当按钮被点击时会将内容添加到状态列表中,此时 LazyColumn 会重组,并显示新的内容
button.setOnClick { state.add("+++++") }
end
end
# 将状态列表中的数据显示到 LazyColumn 中
lls.itemsIndexed(state, nil, nil) do |llss, index, item|
# 状态列表中每个元素显示一个简单的 Text 组件
llss.Text do |text|
text.setModifier do |it|
it.height { |d| d.fromInt(200) }
end
# 设置 Text 组件显示的内容
text.setText(item)
end
end
end
end
end
# 启动一个Activity用于显示脚本界面
$activity.start()
09 December 2025