news 2026/6/13 19:01:09

Compose笔记(七十)--movableContentWithReceiverOf

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Compose笔记(七十)--movableContentWithReceiverOf

这一节主要了解一下Compose中的movableContentWithReceiverOf,在Jetpack Compose开发中movableContentWithReceiverOf是用于创建可移动的组合内容的API,其核心作用是通过保留组合状态,实现将一段Composable内容封装为可在不同组合节点间“移动”的对象,避免重复重组和重新布局,提升性能。简单总结:

API:
MovableContent:可移动内容的核心类型,是封装后的Composable内容句柄
movableContentWithReceiverOf:创建带“接收者(Receiver)”的可移动内容,接收者可传递上下文数据

栗子:

import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.movableContentWithReceiverOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp data class ContentReceiver( val title: String, val color: Color, val count: Int ) @Composable fun MovableContentWithReceiverDemo() { var count by remember { mutableStateOf(0) } var isRed by remember { mutableStateOf(false) } val movableContent = remember { movableContentWithReceiverOf<ContentReceiver> { Box( modifier = Modifier .size(200.dp) .background(this.color.copy(alpha = 0.6f)) .padding(16.dp), contentAlignment = androidx.compose.ui.Alignment.Center ) { Column(horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally) { Text(text = this@movableContentWithReceiverOf.title, color = Color.White, fontSize = 18.sp) Text(text = "计数:${this@movableContentWithReceiverOf.count}", color = Color.White, fontSize = 14.sp) } } } } val receiver = ContentReceiver( title = "带接收者的可复用内容", color = if (isRed) Color.Red else Color.Green, count = count ) Column(modifier = Modifier.padding(16.dp)) { movableContent(receiver) Button( onClick = { count++ }, modifier = Modifier.padding(top = 16.dp) ) { Text(text = "增加计数") } Button( onClick = { isRed = !isRed }, modifier = Modifier.padding(top = 8.dp) ) { Text(text = "切换颜色") } } }
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.ExperimentalComposeApi import androidx.compose.runtime.InternalComposeApi import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.runtime.movableContentWithReceiverOf data class CardReceiver( val cardId: Int, val title: String, val desc: String, val bgColor: Color, val isSelected: Boolean ) @OptIn(ExperimentalComposeApi::class, InternalComposeApi::class) @Composable fun ReusableCardGroup() { var selectedCardId by remember { mutableStateOf(1) } var clickCount by remember { mutableStateOf(0) } val cardContent = remember { movableContentWithReceiverOf<CardReceiver> { Card( modifier = Modifier .fillMaxWidth() .padding(8.dp), shape = RoundedCornerShape(12.dp), border = if (this.isSelected) { BorderStroke(2.dp, Color.Black) } else { BorderStroke(1.dp, Color.Gray) }, colors = CardDefaults.cardColors( containerColor = this.bgColor.copy(alpha = if (this.isSelected) 0.9f else 0.7f) ), elevation = CardDefaults.cardElevation( defaultElevation = if (this.isSelected) 8.dp else 2.dp ) ) { Column( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = this@movableContentWithReceiverOf.title, fontSize = 18.sp, fontWeight = FontWeight.Bold, color = Color.White ) Text( text = "${this@movableContentWithReceiverOf.desc} | 全局点击数:$clickCount", fontSize = 14.sp, color = Color.White.copy(alpha = 0.8f), modifier = Modifier.padding(top = 4.dp) ) Text( text = "卡片ID:${this@movableContentWithReceiverOf.cardId}", fontSize = 12.sp, color = Color.White.copy(alpha = 0.6f), modifier = Modifier.padding(top = 8.dp) ) } } } } Column( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Top ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically ) { Button( onClick = { selectedCardId = if (selectedCardId == 1) 2 else 1 }, modifier = Modifier.padding(4.dp) ) { Text(text = "切换选中卡片") } Button( onClick = { clickCount++ }, modifier = Modifier.padding(4.dp) ) { Text(text = "点击计数+1") } } Column(modifier = Modifier.fillMaxWidth()) { val receiver1 = CardReceiver( cardId = 1, title = "用户信息卡片", desc = "姓名:张三 | 年龄:25", bgColor = Color(0xFF64B5F6), // 蓝色 isSelected = selectedCardId == 1 ) val card1 = cardContent(receiver1) val receiver2 = CardReceiver( cardId = 2, title = "订单信息卡片", desc = "订单号:20260117 | 金额:99元", bgColor = Color(0xFF81C784), // 绿色 isSelected = selectedCardId == 2 ) cardContent(receiver2) } } } @Composable fun MovableContentDemoApp() { Column(modifier = Modifier.fillMaxSize()) { Text( text = "movableContentWithReceiverOf Demo", fontSize = 20.sp, fontWeight = FontWeight.Bold, modifier = Modifier .align(Alignment.CenterHorizontally) .padding(16.dp) ) ReusableCardGroup() } }

注意:
1 必须配合remember使用:movableContentWithReceiverOf需在remember块内调用,以确保组合内容在重新组合时不会被回收。
2 接收者类型需明确 指定正确的接收者类型,否则无法访问布局相关的上下文。
3 参数传递需显式 依赖项应通过参数传入。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 22:32:46

BERT智能语义系统实战案例:语法纠错应用部署详细步骤

BERT智能语义系统实战案例&#xff1a;语法纠错应用部署详细步骤 1. 引言 1.1 业务场景描述 在自然语言处理&#xff08;NLP&#xff09;的实际应用中&#xff0c;语法纠错是一项高频且关键的任务。无论是教育领域的作文批改、办公文档的自动校对&#xff0c;还是社交媒体内…

作者头像 李华
网站建设 2026/6/10 21:21:40

YOLOv9镜像快速入门:只需三步完成模型推理

YOLOv9镜像快速入门&#xff1a;只需三步完成模型推理 在智能安防、工业质检和自动驾驶等现实场景中&#xff0c;目标检测技术正以前所未有的速度落地。然而&#xff0c;从环境配置到模型部署的复杂流程常常成为开发者的主要瓶颈。尤其是面对 YOLOv9 这类前沿模型时&#xff0…

作者头像 李华
网站建设 2026/5/28 13:31:13

蜂鸣器电路入门必看:基本结构与工作原理通俗解释

蜂鸣器电路入门必看&#xff1a;从“嘀”一声到智能提示的底层逻辑你有没有想过&#xff0c;微波炉加热完成时那一声清脆的“嘀”&#xff0c;到底是怎么来的&#xff1f;或者烟雾报警器在深夜突然响起&#xff0c;那穿透力极强的警报声&#xff0c;背后藏着怎样的电子魔法&…

作者头像 李华
网站建设 2026/6/12 19:30:16

HY-MT1.5-1.8B技术解析:支持38种语言原理

HY-MT1.5-1.8B技术解析&#xff1a;支持38种语言原理 1. 引言 随着全球化进程的加速&#xff0c;跨语言沟通需求日益增长。传统机器翻译系统在多语言支持、翻译质量和部署成本之间往往难以平衡。腾讯混元团队推出的 HY-MT1.5-1.8B 模型&#xff0c;作为一款专为高性能翻译任务…

作者头像 李华
网站建设 2026/5/28 19:39:38

Qwen2.5-7B-Instruct JSON输出强制实现:Agent接入部署教程

Qwen2.5-7B-Instruct JSON输出强制实现&#xff1a;Agent接入部署教程 1. 引言 1.1 通义千问2.5-7B-Instruct模型概述 通义千问2.5-7B-Instruct是阿里云于2024年9月发布的Qwen2.5系列中的70亿参数指令微调版本&#xff0c;定位为“中等体量、全能型、可商用”的大语言模型。…

作者头像 李华
网站建设 2026/5/28 23:34:03

Z-Image-Turbo部署建议:生产环境中的容错处理设计

Z-Image-Turbo部署建议&#xff1a;生产环境中的容错处理设计 1. 引言 随着文生图大模型在内容创作、广告设计、游戏资产生成等领域的广泛应用&#xff0c;如何将高性能模型稳定部署至生产环境成为工程落地的关键挑战。Z-Image-Turbo作为阿里达摩院基于DiT架构推出的高效文生…

作者头像 李华