Jetpack compose:炫酷的按钮点击效果

Jetpack compose:炫酷的按钮点击效果

justly
屏幕的每个组件在与用户交互时都有其给用户反馈的方式。例如,当用户触摸 Toggle 按钮时,它会更改其状态以响应交互。这种交互给用户一种感觉。

在此博客中,我们将实现一些自定义点击效果,使您的按钮点击更具吸引力。

默认情况下,按钮在被触摸时会显示波纹效果。您可以根据您的要求自定义波纹颜色、alpha 等,但我们不打算在本文中介绍。是的,但我们将学习一些禁用默认连锁反应的方法。

我们要做些什么?

缩放效果
点击效果
震动效果
单击动画形状
3种禁用默认点击效果的方法
让我们开始吧…

缩放效果

scale-effect
对于这种效果,我们只需要更改按钮的比例即可获得漂亮的弹跳效果。代码如下:

enum class ButtonState { Pressed, Idle }
fun Modifier.bounceClick() = composed {
    var buttonState by remember { mutableStateOf(ButtonState.Idle) }
    val scale by animateFloatAsState(if (buttonState == ButtonState.Pressed) 0.70f else 1f)

    this
        .graphicsLayer {
            scaleX = scale
            scaleY = scale
        }
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null,
            onClick = {  }
        )
        .pointerInput(buttonState) {
            awaitPointerEventScope {
                buttonState = if (buttonState == ButtonState.Pressed) {
                    waitForUpOrCancellation()
                    ButtonState.Idle
                } else {
                    awaitFirstDown(false)
                    ButtonState.Pressed
                }
            }
        }
}

没什么特别的,只是根据按钮状态对缩放值进行动画处理。让我们将此修改器应用于按钮。

@Composable
fun PulsateEffect() {
    Button(onClick = {
        // clicked
    }, shape = RoundedCornerShape(12.dp),
        contentPadding = PaddingValues(16.dp),
        modifier = Modifier.bounceClick()) {
        Text(text = "Click me")
    }
}

下面是一个实用的App,UI效果是不是很棒
justly

按压效果

我们将稍微移动按钮以使其具有按压效果。

enum class ButtonState { Pressed, Idle }
fun Modifier.pressClickEffect() = composed {
    var buttonState by remember { mutableStateOf(ButtonState.Idle) }
    val ty by animateFloatAsState(if (buttonState == ButtonState.Pressed) 0f else -20f)

    this
        .graphicsLayer {
            translationY = ty
        }
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null,
            onClick = {  }
        )
        .pointerInput(buttonState) {
            awaitPointerEventScope {
                buttonState = if (buttonState == ButtonState.Pressed) {
                    waitForUpOrCancellation()
                    ButtonState.Idle
                } else {
                    awaitFirstDown(false)
                    ButtonState.Pressed
                }
            }
        }
}

没什么新的,和我们之前的效果一样,我们只是tranlateY在按钮状态变化时设置了动画值。

@Composable
fun PressEffect() {
   Button(onClick = {
        //Clicked
    }, shape = RoundedCornerShape(12.dp), contentPadding = PaddingValues(16.dp),
        modifier = Modifier.pressClickEffect()) {
        Text(text = "Click me")
    }
}

click-effect

震动效果

摇动效果对于显示无效交互非常有用,例如,注册表单上的无效数据。

对于摇动,我们只需要实现可重复的动画。

fun Modifier.shakeClickEffect() = composed {
    var buttonState by remember { mutableStateOf(ButtonState.Idle) }
    
val tx by animateFloatAsState(
        targetValue = if (buttonState == ButtonState.Pressed) 0f else -50f,
        animationSpec = repeatable(
            iterations = 2,
            animation = tween(durationMillis = 50, easing = LinearEasing),
            repeatMode = RepeatMode.Reverse
        )
    )
    this
        .graphicsLayer {
            translationX = tx
        }
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null,
            onClick = { }
        )
        .pointerInput(buttonState) {
            awaitPointerEventScope {
                buttonState = if (buttonState == ButtonState.Pressed) {
                    waitForUpOrCancellation()
                    ButtonState.Idle
                } else {
                    awaitFirstDown(false)
                    ButtonState.Pressed
                }
            }
        }
}

在这里,我们添加了可重复的动画来将按钮移动 2 次以实现摇动效果。

@Composable
fun ShakeEffect(){

    Button(onClick = {
        //Clicked
    }, shape = RoundedCornerShape(12.dp), contentPadding = PaddingValues(16.dp),
        modifier = Modifier.shakeClickEffect()) {
        Text(text = "Click me")
    }
}

震动效果
shake-effect

单击动画形状

为此,我们将为视图角半径设置动画。

val interactionSource = remember { MutableInteractionSource() }
val isPressed = interactionSource.collectIsPressedAsState()
val cornerRadius by animateDpAsState(targetValue = if (isPressed.value) 10.dp else 50.dp)

这里我们使用animateDpAsStateAPI 来动画半径dp值

现在,将此半径应用于可组合

Box(
    modifier = Modifier
        .background(color = pink, RoundedCornerShape(cornerRadius))
        .size(100.dp)
        .clip(RoundedCornerShape(cornerRadius))
        .clickable(
            interactionSource = interactionSource,
            indication = rememberRipple()
        ) {
            //Clicked
        }
        .padding(horizontal = 20.dp),
    contentAlignment = Alignment.Center
) {
    Text(
        text = "Click!",
        color = Color.White
    )
}

动画效果
animation-effect

3种禁用默认点击效果的方法

1.使用自定义InteractionSource

InteractionSource表示与组件发出的事件相对应的交互流。这些交互可用于更改组件在不同状态下的显示方式,例如当组件被按下或拖动时。

class NoRippleInteractionSource : MutableInteractionSource {

    override val interactions: Flow<Interaction> = emptyFlow()

    override suspend fun emit(interaction: Interaction) {}

    override fun tryEmit(interaction: Interaction) = true
}

所以这里我们有一个返回空流,这意味着按钮不会对不同的点击状态做出反应,例如按钮按下或拖动。

如何使用这个自定义的InteractionSource?按钮有interactionSource属性。

@Composable
fun NoRippleEffect1() {
   
    Button(
        onClick = {
            //Clicked
        },
        interactionSource = remember { NoRippleInteractionSource() },
        shape = RoundedCornerShape(12.dp),
        contentPadding = PaddingValues(16.dp),
    ) {
        Text(text = "Button without Ripple Effect")
    }
}

检查此输出。你将有一个没有任何效果的按钮。
NoRippleEffect

2.通过“指示”去除视觉效果

指示表示发生某些交互时出现的视觉效果。

例如:按下组件时显示波纹效果,或聚焦组件时高亮显示。

该按钮没有指示属性,因此将创建一个具有Box可组合性的自定义按钮。

@Composable
fun NoRippleEffect2() {
    Box(
        modifier = Modifier
            .height(height = 38.dp)
            .background(
                color = pink,
                shape = RoundedCornerShape(percent = 12)
            )
            .clickable(
                interactionSource = remember { MutableInteractionSource() },
                indication = null
            ) {
                //Clicked
            }
            .padding(horizontal = 20.dp),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "Click me",
            color = Color.White
        )
    }
}

3.通过使用自定义波纹主题

private object NoRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = // Ripple color

    @Composable
    override fun rippleAlpha(): RippleAlpha = RippleAlpha(0.0f, 0.0f, 0.0f, 0.0f)
}

RippleAlpha 为不同的交互定义了波纹/状态层的 alpha。我们为所有状态添加了 0.0f,这意味着没有连锁反应。将自定义主题应用到按钮使用CompositionLocalProvider

@Composable
fun NoRippleEffect3() {
    CompositionLocalProvider(LocalRippleTheme provides NoRippleTheme) {
        Button(
            onClick = {
                //Clicked
            }, shape = RoundedCornerShape(12.dp),
            contentPadding = PaddingValues(16.dp)
        ) {
            Text(text = "Click me")
        }
    }
}

文章所涉源码地址:

https://github.com/cp-radhika-s/CoolButtonClickEffects

结论

到目前为止,我们已经学习了一些自定义按钮点击效果。按钮是任何应用程序的重要组成部分,值得付出更多努力使您的按钮更具吸引力和交互性。您可以使用 Jetpack compose 的 Animation API 实现许多此类效果。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Air700E开发板|移芯EC618|4G Cat.1模组:概述及PinOut

文章目录基础资料概述主要功能外设分布PinOut&#xff08;管脚定义&#xff09;管脚功能说明固件升级正常开机模式&#xff1a;下载模式&#xff1a;IO 电平选择基础资料 Air700E文档中心 概述 EVB-Air700E 开发板是合宙通信推出的基于 Air700E 模组所开发的&#xff0c;包含…

AI遮天传 NLP-词表示

本文重点在第三部分“词嵌入”及对Word2vec的介绍&#xff0c;前面的知识主要用于小白对词表示和一些定义、名称的理解&#xff0c;和对一些方法不足的思考。一、词表示1.1 词表示的定义词表示是一种将自然语言中的词转换为机器可理解含义的过程其中意思&#xff08;meaning&am…

Docker之安装Docker

安装Docker1. Docker 基本组成2. 安装Docker3. 阿里云镜像加速4. 底层原理1. Docker 基本组成 镜像&#xff08;image&#xff09; docker 镜像就好比是一个模板&#xff0c;可以同通过这个模板来创建容器服务&#xff0c;如&#xff1a;tomcat 镜像 > run > tomcat1 容器…

网络技术这十个术语你知道吗?

你好&#xff0c;这里是网络技术联盟站。 网络技术术语是指在计算机网络领域中所使用的专业术语。由于计算机技术的快速发展&#xff0c;网络技术术语也在不断地更新和发展。本文将对网络技术术语进行一些介绍和解释&#xff0c;以帮助读者更好地了解和掌握网络技术。 一、协…

内网Nexus代理yum、epel 源私有仓库 + 内网设备配置(centos)

一、准备 一些常用的镜像开源站 yum: 阿里开源镜像源&#xff1a;http://mirrors.aliyun.com/centos 网易开源镜像站&#xff1a;http://mirrors.163.com/ Centos社区镜像站&#xff1a;http://mirror.centos.org/centos/ 中科大开源镜像站&#xff1a;http://centos.ustc.edu…

Web3中文|World ID与GPT-4同时上线,OpenAI创始人的另一场探险?

这两天GPT-4的到来&#xff0c;再次成为朋友圈及媒体热议的话题。此次升级、更新让大家看到了AI给科技和社会带来的潜在挑战性甚至革命性。在赞叹AI迅速发展的同时&#xff0c;也让人再次聚焦关注其背后拥有超强开发和创新能力的OpenAI团队。 令人刮目相看的是&#xff0c;由A…

JMeter使用教程

作为一名开发工程师&#xff0c;当我们接到需求的时候&#xff0c;一般就是分析需要&#xff0c;确定思路&#xff0c;编码&#xff0c;自测&#xff0c;然后就可以让测试人员去测试了。在自测这一步&#xff0c;作为开发人员&#xff0c;很多时候就是测一下业务流程是否正确&a…

【JAVA程序设计】(C00125)基于Springboot的人事管理系统

基于Springboot的人事管理系统项目简介项目获取开发环境项目技术运行截图项目简介 基于Springboot框架开发的人事管理系统共分为四个角色&#xff1a;系统管理员、财务专员、人事专员、普通用户 管理员角色包含以下功能&#xff1a; 管理员拥有所有功能&#xff1a;绩效考核&a…

华为OD机试题,用 Java 解【叠放书籍】问题 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:叠放书籍 题目 书籍的长宽都是…

RabbitMQ中死信队列和延迟队列

目录一、死信队列1.过期时间代码实现2.长度限制代码实现3.测试消息拒收4.死信队列小结二、延迟队列1.代码实现1.1 生产者1.2 生产者一、死信队列 死信队列&#xff0c;英文缩写&#xff1a;DLX 。Dead Letter Exchange&#xff08;死信交换机&#xff09;&#xff0c;当消息成…

Makefile第三课:C语言的编译

目录C语言的编译前言1.Fundamental Compiling2.Comiling C2.1 Preprocessing2.2 Generating Assembly Language2.3 Source File to Object File2.4 Single Source to Executable2.5 Multiple Sources to Executable3.Creating a Static Library4.Creating a Shared Library5.总…

贯穿设计模式第二话--开闭职责原则

&#x1f973;&#x1f973;&#x1f973; 茫茫人海千千万万&#xff0c;感谢这一刻你看到了我的文章&#xff0c;感谢观赏&#xff0c;大家好呀&#xff0c;我是最爱吃鱼罐头&#xff0c;大家可以叫鱼罐头呦~&#x1f973;&#x1f973;&#x1f973; 从今天开始&#xff0c;将…

java基础学习——字符流

1.为什么会出现字符流&#xff1a; 由于字节流 操作中文不是特别的方便&#xff0c;所以java就提供字符流 字符流字节流编码表 用字节流复制文本文件时&#xff0c;文本文件也会有中文&#xff0c;但是没有问题&#xff0c;原因是最终底层操作会自动进行字节拼接成中文&#xf…

摄影入门 | 相机的基本原理

一、获取图像——小孔成像实验 小孔成像实验中&#xff0c;点燃蜡烛&#xff0c;会在小孔另一面的白纸上看到一个倒立的烛焰。 此现象可以用来解释物理学原理&#xff1a;光在同种均匀介质中&#xff0c;在不受引力作用干扰的情况下沿直线传播。 这样&#xff0c;我们就用一种…

从零开始搭建游戏服务器 第一节 创建一个简单的服务器架构

目录引言技术选型正文创建基础架构IDEA创建项目添加Netty监听端口编写客户端进行测试总结引言 由于现在java web太卷了&#xff0c;所以各位同行可以考虑换一个赛道&#xff0c;做游戏还是很开心的。 本篇教程给新人用于学习游戏服务器的基本知识&#xff0c;给新人们一些学习…

伪静态技术

网址和纯静态一样&#xff0c;只是&#xff0c;其内部仍旧需要查询数据库&#xff1a;如果有一个页面&#xff0c;希望这个页面利于seo,但是有不适合使用真静态&#xff0c;比如csdn论坛帖子&#xff0c;可以考虑使用伪静态&#xff0c;即: 形式上是一个静态地址&#xff0c;比…

Chapter7.2:MATLAB在频率法中的应用及频率法稳定性分析

该系列博客主要讲述Matlab软件在自动控制方面的应用&#xff0c;如无自动控制理论基础&#xff0c;请先学习自动控制系列博文&#xff0c;该系列博客不再详细讲解自动控制理论知识。 自动控制理论基础相关链接&#xff1a;https://blog.csdn.net/qq_39032096/category_10287468…

PyTorch 深度学习实战 | DIEN 模拟兴趣演化的序列网络

01、实例&#xff1a;DIEN 模拟兴趣演化的序列网络深度兴趣演化网络(Deep Interest Evolution Network,DIEN)是阿里巴巴团队在2018年推出的另一力作,比DIN 多了一个Evolution,即演化的概念。在DIEN 模型结构上比DIN 复杂许多,但大家丝毫不用担心,我们将DIEN 拆解开来详细地说明…

Intel 处理器 macOS降级到Big Sur

1 创建可引导的 macOS 安装器 将移动硬盘作安装 Mac 操作系统的启动磁盘。 创建可引导安装器需要满足的条件 移动硬盘&#xff08;格式化为 Mac OS 扩展格式&#xff09;&#xff0c;至少有 14GB 可用空间已下载 macOS Big Sur的安装器 2 下载 macOS macOS Big Sur安装器会…

【GPT4】微软 GPT-4 测试报告(1)总体介绍

欢迎关注【youcans的AGI学习笔记】原创作品&#xff0c;火热更新中 微软 GPT-4 测试报告&#xff08;1&#xff09;总体介绍 微软 GPT-4 测试报告&#xff08;2&#xff09;多模态与跨学科能力 微软 GPT-4 测试报告&#xff08;3&#xff09;GPT4 的编程能力 【GPT4】微软 GPT-…
最新文章