欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Compose笔记(二十八)--加水印

Compose笔记(二十八)--加水印

2025/6/22 23:11:08 来源:https://blog.csdn.net/ljt2724960661/article/details/148808006  浏览:    关键词:Compose笔记(二十八)--加水印

        这一节主要了解一下Compose中的加水印,在开发中,有时候我们需要对应用界面做水印效果,水印是指覆盖在应用界面上的半透明标识或图案,通常用于版权声明、内容归属标记或安全防护,Compose中水印效果实现方式,简单总结如下:

场景:
1. 版权保护与内容归属
图片编辑类App在未保存作品上添加 “草稿” 水印;
文档阅读类App在页面显示用户账号或机构名称,防止截图外泄。
2. 安全与保密需求
敏感信息追踪:在内部系统添加包含用户ID、时间戳的动态水印,便于追溯泄露源头。
防截屏保护:部分金融类App通过水印提示 “截屏可能泄露信息”,增强安全警示。
3. 品牌与视觉识别
强化品牌认知:在产品演示界面、宣传材料中添加品牌logo水印,提升曝光度。
区分版本属性:免费版App添加 “试用版” 水印,付费版则隐藏,作为功能区分标识。

栗子:

使用LazyGrid

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp@Composable
fun WatermarkLazyGrid(markText: String,textStyle: TextStyle = TextStyle(fontSize = 14.sp,fontWeight = FontWeight.Normal,color = Color(0.5f, 0.5f, 0.5f, 0.3f)),columns: Int = 3,rows: Int = 5,rotation: Float = -25f,content: @Composable BoxScope.() -> Unit,
) {Box(modifier = Modifier.fillMaxSize()) {content()LazyVerticalGrid(columns = GridCells.Fixed(columns),modifier = Modifier.fillMaxSize().pointerInput(Unit) {awaitPointerEventScope {while (true) {awaitPointerEvent()}}}) {items(columns * rows) { index ->Box(modifier = Modifier.fillMaxSize().graphicsLayer {rotationZ = rotation},contentAlignment = Alignment.Center) {Text(text = markText,style = textStyle,modifier = Modifier.padding(16.dp))}}}}
}调用:WatermarkLazyGrid("HelloWorld") {FixedGridExample()}

 使用Canvas

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.sp@Composable
fun WatermarkOverlay(text: String,alpha: Float = 0.1f,textSize: androidx.compose.ui.unit.TextUnit = 18.sp,angle: Float = 30f,content: @Composable BoxScope.() -> Unit,
) {val textMeasurer = rememberTextMeasurer()Canvas(modifier = Modifier.fillMaxSize()) {val canvasWidth = size.widthval canvasHeight = size.heightval textLayoutResult = textMeasurer.measure(text = text,style = TextStyle(fontSize = textSize, color = Color.Black.copy(alpha = alpha)))val textWidth = textLayoutResult.size.width.toFloat()val textHeight = textLayoutResult.size.height.toFloat()val xStep = textWidth * 2val yStep = textHeight * 2for (x in -canvasWidth.toInt()..canvasWidth.toInt() step xStep.toInt()) {for (y in -canvasHeight.toInt()..canvasHeight.toInt() step yStep.toInt()) {rotate(degrees = angle, pivot = Offset(x.toFloat(), y.toFloat())) {drawText(textMeasurer = textMeasurer,text = text,topLeft = Offset(x.toFloat(), y.toFloat()))}}}}
}

用Modifier.graphicsLayer

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.sp@Composable
fun WatermarkPlay(markText: String,textStyle: TextStyle = TextStyle(fontSize = 14.sp,fontWeight = FontWeight.Normal,color = Color(0.5f, 0.5f, 0.5f, 0.3f)),columns: Int = 3,rows: Int = 5,rotation: Float = -25f,content: @Composable BoxScope.() -> Unit,
) {Box(modifier = Modifier.fillMaxSize()) {content()BoxWithConstraints(modifier = Modifier.fillMaxSize()) {val boxWidth = constraints.maxWidth.toFloat()val boxHeight = constraints.maxHeight.toFloat()val horizontalSpacing = boxWidth / (columns + 1)val verticalSpacing = boxHeight / (rows + 1)for (row in 0 until rows) {for (col in 0 until columns) {val x = horizontalSpacing * (col + 1)val y = verticalSpacing * (row + 1)Text(text = markText,style = textStyle,modifier = Modifier.offset { IntOffset(x.toInt(), y.toInt()) }.graphicsLayer {rotationZ = rotationalpha = 0.3f // 透明度})}}}}
}使用:
WatermarkPlay("HelloWorld") {FixedGridExample()}
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Card@Composable
fun FixedGridExample() {val items = List(6) { "Item $it" }LazyVerticalGrid(columns = GridCells.Fixed(3), // 固定3列contentPadding = PaddingValues(20.dp),verticalArrangement = Arrangement.spacedBy(4.dp),horizontalArrangement = Arrangement.spacedBy(12.dp)) {items(items) { item ->Card(onClick = {},modifier = Modifier.height(100.dp)) {Box(contentAlignment = Alignment.Center,modifier = Modifier.fillMaxSize()) {Text(item)}}}}
}

总结:
1. Canvas方案:
    适合复杂图案或高性能需求场景
    需要手动处理文本测量和绘制
2. Modifier方案:
    代码最简洁,利用Compose现有API
    适合简单文本水印场景
3. LazyGrid方案:
    布局最灵活,支持滚动和动态内容
    适合需要响应式布局的场景
    比Canvas和Modifier方案略重

注意:
1 透明度与可读性平衡,水印过深会影响主内容,过浅则起不到作用,建议使用alpha=0.1 ~ 0.2的半透明效果.
2 水印若覆盖在可点击元素上,可能拦截触摸事件,使用pointerInput(Unit) {}让水印层忽略触摸事件.    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词