Compose笔记(二十五)--Brush

        这一节主要了解一下Compose中Brush,在Jetpack Compose里,Brush是一个重要的 API,它用于定义填充图形的颜色渐变或图案,能够为界面元素添加丰富的视觉效果。简单总结如下:

1 常见场景
填充形状(圆形、矩形等)
创建渐变效果
实现纹理或图案
组合多个 Brush

2. 常用 Brush 类型

2.1 纯色填充(SolidColor)
// 直接使用Color作为Brush
drawCircle(color = Color.Red)
// 或显式创建SolidColor Brush
val brush = SolidColor(Color.Blue)
drawRect(brush = brush)2.2 线性渐变(LinearGradientBrush)
val brush = LinearGradientBrush(colors = listOf(Color.Red, Color.Blue),start = Offset(0f, 0f), end = Offset(size.width, size.height)  
)
drawRect(brush = brush)2.3 径向渐变(RadialGradientBrush)
val brush = RadialGradientBrush(colors = listOf(Color.Yellow, Color.Transparent),center = Offset(size.width / 2, size.height / 2), radius = size.minDimension / 2  // 半径
)
drawCircle(brush = brush, radius = size.minDimension / 2)2.4 扫描渐变(SweepGradientBrush)
val brush = SweepGradientBrush(colors = listOf(Color.Red, Color.Green, Color.Blue),center = Offset(size.width / 2, size.height / 2) 
)
drawCircle(brush = brush, radius = size.minDimension / 2)2.5 图像 Brush(ImageBrush)
val imageBitmap = painterResource(id = R.drawable.example).asImageBitmap()
val brush = ImageBrush(image = imageBitmap,contentScale = ContentScale.Crop
)
drawRect(brush = brush)

栗子:

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch@Composable
fun GradientExample() {val gradientOffset = remember { Animatable(0f) }LaunchedEffect(Unit) {launch {gradientOffset.animateTo(targetValue = 100f,animationSpec = infiniteRepeatable(animation = tween(durationMillis = 2000,easing = FastOutSlowInEasing)))}}val dynamicGradient = Brush.linearGradient(colors = listOf(Color.Red, Color.Yellow),start = androidx.compose.ui.geometry.Offset(0f, 0f),end = androidx.compose.ui.geometry.Offset(gradientOffset.value, gradientOffset.value))Box(modifier = Modifier.size(100.dp).background(brush = dynamicGradient))
}
import androidx.compose.animation.core.*
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import kotlin.math.cos
import kotlin.math.sin@Composable
fun RainbowGradient() {val angle by animateFloatAsState(targetValue = 360f,animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing)))val colors = listOf(Color(0xFFFF0000), // 红Color(0xFFFF7F00), // 橙Color(0xFFFFFF00), // 黄Color(0xFF00FF00), // 绿Color(0xFF0000FF), // 蓝Color(0xFF4B0082), // 靛Color(0xFF9400D3)  // 紫)Canvas(modifier = Modifier.fillMaxSize()) {val radians = angle * (Math.PI / 180).toFloat()val width = size.widthval height = size.heightval start = Offset(x = width / 2 + width / 2 * cos(radians),y = height / 2 + height / 2 * sin(radians))val end = Offset(x = width / 2 - width / 2 * cos(radians),y = height / 2 - height / 2 * sin(radians))drawRect(brush = Brush.linearGradient(colors = colors,start = start,end = end,tileMode = androidx.compose.ui.graphics.TileMode.Mirror))}
}

注意:
1 避免重复创建 Brush 实例:每次重组都创建新的Brush会导致不必要的内存分配和GC压力。使用remember缓存 Brush:

val gradientBrush = remember {LinearGradientBrush(colors = listOf(Color.Red, Color.Blue),start = Offset.Zero,end = Offset(size.width, size.height))
}

2 优先使用内置Brush工厂方法直接调用Brush.linearGradient()等方法,避免手动创建子类:

val brush = Brush.linearGradient(colors = listOf(...))// 不推荐
val brush = LinearGradientBrush(...)

3 对静态内容使用drawWithCache,缓存复杂Brush计算结果,避免重复绘制:

Modifier.drawWithCache {val cachedBrush = createComplexBrush()onDraw { drawRect(brush = cachedBrush) }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

离线服务器Python环境配置指南

离线服务器Python环境配置指南:避坑与实战 0. 场景分析:当服务器与世隔绝时 典型困境: 无法访问国际网络(如PyPI、Conda官方源)服务器处于内网隔离环境安全策略限制在线安装 解决方案矩阵: 方法适用场…

Mac下载bilibili视频

安装 安装 yt-dlp brew install yt-dlp安装FFmpeg 用于合并音视频流、转码等操作 brew install ffmpeg使用 下载单个视频 查看可用格式 yt-dlp -F --cookies-from-browser chrome "https://www.bilibili.com/video/BV15B4y1G7F3?spm_id_from333.788.recommend_more_vid…

常见的实时通信技术(轮询、sse、websocket、webhooks)

1. HTTP轮询:最老实的办法 刚开始做实时功能时,我第一个想到的就是轮询。特别简单直白,就像你每隔5分钟就刷新一次朋友圈看看有没有新消息一样。 短轮询:勤快但费劲 短轮询就是客户端隔三差五地问服务器:"有新…

Elasticsearch Fetch阶段面试题

Elasticsearch Fetch阶段面试题 🚀 目录 基础原理性能优化错误排查场景设计底层机制总结基础原理 🔍 面试题1:基础原理 题目: 请描述Elasticsearch分布式搜索中Query阶段和Fetch阶段的工作流程,为什么需要将搜索过程拆分为这两个阶段? 👉 点击查看答案 查询流程…

vr制作公司提供什么服务?

随着科技的迅猛进步,虚拟现实(Virtual Reality,简称VR)技术已经悄然渗透到我们的日常生活与工作中,成为推动数字化转型的重要力量。VR制作公司,作为前沿领域的探索者和实践者,以专业的技术和创新…

COCO数据集神经网络性能现状2025.5.18

根据当前搜索结果,截至2025年5月,COCO数据集上性能最佳的神经网络模型及其关键参数如下: 1. D-FINE(中科大团队) 性能参数: 在COCO数据集上以78 FPS的速度实现了59.3%的平均精度(AP&#xff0…

Sentinel原理与SpringBoot整合实战

前言 随着微服务架构的广泛应用,服务和服务之间的稳定性变得越来越重要。在高并发场景下,如何保障服务的稳定性和可用性成为了一个关键问题。阿里巴巴开源的Sentinel作为一个面向分布式服务架构的流量控制组件,提供了从流量控制、熔断降级、…

Ubuntu 20.04 报错记录: Matplotlib 无法使用 OpenCV 的 libqxcb.so

网上查了一下这个报错,有很多解决方案,但是都不是针对 OpenCV 触发的这种 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in " */lib/*/site-packages/cv2/qt/plugins" even though it was found. 本文的方案是牺牲 …

配置代理服务器访问github、google

配置代理服务器访问github、google 背景与原理配置环境配置步骤云主机配置Windows客户端创建SSH隧道安装 Windows 内置 OpenSSHssh config 配置文件创建动态代理隧道 浏览器代理设置 验证浏览器访问google、githubssh 访问github 背景与原理 由于网络政策限制,中国…

网络学习-利用reactor实现http请求(六)

一、实现HTTP请求 1、印象里面,总有人说C/C语言不能实现HTTP请求,其实不然。C/C语言完全可以实现HTTP请求。通过对select,poll,epoll等IO多路复用技术的学习以及reactor模式的学习,完全能够实现HTTP请求。 2、webserver 主要解决两个问题 …

【VSCode】修改侧边文件资源管理器中的文件夹折叠模式

默认为紧凑模式: 然后我们勾选该项为宽松模式:

信息化时代国产主板如何防止信息泄露?

在数字化时代,每一份机密的泄露都可能成为我们的致命伤,尤其是如今网络如此发达的5G时代,如何防止网络信息泄密,已经成为每个人必须直面的问题。随着网络安全问题日益严重,企业和个人对网络安全的重视程度不断加深&…

vue的简单使用

1.vue的引入 引入函数&#xff0c;创建createApp对象 <div id"app">{{ message }}</div><script type"module">import { createApp, ref } from https://unpkg.com/vue3/dist/vue.esm-browser.jscreateApp({setup() {const message re…

【图像生成大模型】HunyuanVideo:大规模视频生成模型的系统性框架

HunyuanVideo&#xff1a;大规模视频生成模型的系统性框架 引言HunyuanVideo 项目概述核心技术1. 统一的图像和视频生成架构2. 多模态大语言模型&#xff08;MLLM&#xff09;文本编码器3. 3D VAE4. 提示重写&#xff08;Prompt Rewrite&#xff09; 项目运行方式与执行步骤1. …

DPDK 技术详解:榨干网络性能的“瑞士军刀”

你是否曾感觉&#xff0c;即使拥有顶级的服务器和万兆网卡&#xff0c;你的网络应用也总是“喂不饱”硬件&#xff0c;性能总差那么一口气&#xff1f;传统的网络处理方式&#xff0c;就像在高速公路上设置了太多的收费站和检查点&#xff0c;限制了数据包的“奔跑”速度。 今…

力扣网-复写零

1.题目要求 2.题目链接 1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 3.题目解答 class Solution {public void duplicateZeros(int[] arr) {int cur0,dest-1,narr.length;while(cur<n){//遇到0就dest走两步if(arr[cur]0){dest2;}//遇到非零元素dest就走一步els…

STL中的Vector(顺序表)

vector容器的基本用法&#xff1a; template<class T> class vector { T* _a; size_t size; size_t capacity; } 尾插和遍历&#xff1a; vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3);//遍历 for(int i0;i<v.size();i) {cout<<…

Hass-Panel - 开源智能家居控制面板

文章目录 ▎项目介绍&#xff1a;预览图▎主要特性安装部署Docker方式 正式版Home Assistant Addon方式详细安装方式1. Home Assistant 插件安装&#xff08;推荐&#xff09;2. Docker 安装命令功能说明 &#xff1a;3. Docker Compose 安装升级说明Docker Compose 版本升级 功…

ctfhub技能书http协议

http://challenge-ffe8afcf1a75b867.sandbox.ctfhub.com:10800/index.php curl -v -X CTFHUB http://challenge-ffe8afcf1a75b867.sandbox.ctfhub.com:10800/index.php curl&#xff1a;用于发送 HTTP 请求的命令行工具。 -v&#xff08;--verbose&#xff09;&#xff1a;开启…

Eigen与OpenCV矩阵操作全面对比:最大值、最小值、平均值

功能对比总表 功能Eigen 方法OpenCV 方法主要区别最大值mat.maxCoeff(&row, &col)cv::minMaxLoc(mat, NULL, &maxVal, NULL, &maxLoc)Eigen需要分开调用&#xff0c;OpenCV一次获取最小值mat.minCoeff(&row, &col)cv::minMaxLoc(mat, &minVal, NU…