news 2026/8/21 23:35:24

Flutter---右滑显示删除按钮

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter---右滑显示删除按钮

效果图

关键控件

Transform.translate - 平移变换组件

基本语法

Transform.translate( offset: Offset(dx, dy), // 必需参数 child: Widget, // 要平移的子组件 transformHitTests: true, // 可选 )

核心参数:offset- 平移偏移量

dx: 水平方向偏移量(正数向右,负数向左) dy: 垂直方向偏移量(正数向下,负数向上)

滑动中监听

onHorizontalDragStart: // 滑动开始时触发 onHorizontalDragUpdate: // 滑动过程中连续触发 onHorizontalDragEnd: // 滑动结束时触发 onHorizontalDragCancel: // 滑动被取消时触发
关键知识点

1.为什么向右滑动details.delta.dx为正数,向左滑动details.delta.dx为负数,

坐标系理解: 在Flutter的滑动事件中: 屏幕坐标系:原点(0,0)在屏幕左上角 X轴:从左到右是正方向 Y轴:从上到下是正方向 delta.dx 的含义: delta.dx 表示水平方向的位移变化量 正值 = 向右滑动(手指从左边移动到右边) 负值 = 向左滑动(手指从右边移动到左边) (0,0) 左上角 ┌─────────────┐ │ │ │ +------│----> X轴 (正方向向右) │ | │ │ ↓ │ │ Y轴 │ │ (正方向向下) │ └─────────────┘
实现步骤

1.定义变量

double _slideOffset = 0.0; //当前滑动偏移量 final double _maxSlideDistance = 60.0; // 最大滑动距离,删除按钮的宽度也设置了这个值 bool _showDeleteButton = false;//是否显示删除按钮提示

2.圆角矩形叠在删除按钮上面,所以要用stack组件,先构建删除按钮

// 删除按钮(在内容下面) Positioned.fill( child: Align( alignment: Alignment.centerRight, child: GestureDetector( onTap: (){ //删除按钮的点击时间 print("点击删除按钮"); }, child: Container( width: 60, height: 40, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(20), ), child: Center( child: Icon( Icons.delete, color: Colors.white, size: 20, ), ), ), ) ), ),

3.定义可滑动的内容

// 可滑动的内容 GestureDetector( //处理滑动更新 onHorizontalDragUpdate: (details) { setState(() { //a -= b;表达式表示:a = a - b //details.delta.dx表示用户手指在X轴移动的距离,向右滑动details.delta.dx为正数,向左滑动details.delta.dx为负数,(补充说明) //从 _slideOffset 中减去 details.delta.dx 的值。 _slideOffset -= details.delta.dx; //限制滑动范围 if (_slideOffset < 0) _slideOffset = 0; //不能向右移 if (_slideOffset > _maxSlideDistance) _slideOffset = _maxSlideDistance; //移动距离不能超过设置的最大滑动距离 //显示/隐藏删除按钮的逻辑 if (_slideOffset > 20 && !_showDeleteButton) {//左移大于20且删除按钮没有显示的时候 _showDeleteButton = true; //显示 } else if (_slideOffset < 20 && _showDeleteButton) { _showDeleteButton = false; } }); }, //处理滑动结束 onHorizontalDragEnd: (details) { if (_slideOffset > 30) { //用户左滑的距离大于30,则显示删除按钮 _slideOffset = _maxSlideDistance; } else { //否则就不显示删除按钮 _slideOffset = 0; _showDeleteButton = false; } setState(() {}); }, child: Transform.translate( //平移变换组件 //offset(dx,dy) //dx表示X轴偏移,dy表示Y轴偏移 //Offset(正数, 0) → 向右移动 ; Offset(负数, 0) → 向左移动 //Offset(10, 0)表示向右移动10像素 ; Offset(-10, 0)表示向左移动10像素 ;Offset(0, 0)表示不移动 offset: Offset(-_slideOffset, 0),//注意这里这里有个负号,所以这个小于零变成右移,大于零变成左移 child: Container( width: 320, height: 40, decoration: BoxDecoration( color: Color(0xFF1E2134), borderRadius: BorderRadius.circular(20), ), child: Center( child: Text( //通过是否显示删除按钮,来更新文本 _showDeleteButton ? "松手删除" : "向右滑动显示删除", style: TextStyle( color: Colors.white, fontSize: 16, ), ), ), ), ), ),

代码实例

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<StatefulWidget> createState() => _MeditationPageState(); } class _MeditationPageState extends State<HomePage> with SingleTickerProviderStateMixin { double _slideOffset = 0.0; //当前滑动偏移量 final double _maxSlideDistance = 60.0; // 最大滑动距离,删除按钮的宽度也设置了这个值 bool _showDeleteButton = false;//是否显示删除按钮提示 @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: Container( width: double.infinity, height: double.infinity, child: Center( child: Container( width: 320, margin: EdgeInsets.symmetric(horizontal: 20), child: Stack( children: [ // 删除按钮(在内容下面) Positioned.fill( child: Align( alignment: Alignment.centerRight, child: GestureDetector( onTap: (){ //删除按钮的点击时间 print("点击删除按钮"); }, child: Container( width: 60, height: 40, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(20), ), child: Center( child: Icon( Icons.delete, color: Colors.white, size: 20, ), ), ), ) ), ), // 可滑动的内容 GestureDetector( //处理滑动更新 onHorizontalDragUpdate: (details) { setState(() { //a -= b;表达式表示:a = a - b //details.delta.dx表示用户手指在X轴移动的距离,向右滑动details.delta.dx为正数,向左滑动details.delta.dx为负数,(补充说明) //从 _slideOffset 中减去 details.delta.dx 的值。 _slideOffset -= details.delta.dx; //限制滑动范围 if (_slideOffset < 0) _slideOffset = 0; //不能向右移 if (_slideOffset > _maxSlideDistance) _slideOffset = _maxSlideDistance; //移动距离不能超过设置的最大滑动距离 //显示/隐藏删除按钮的逻辑 if (_slideOffset > 20 && !_showDeleteButton) {//左移大于20且删除按钮没有显示的时候 _showDeleteButton = true; //显示 } else if (_slideOffset < 20 && _showDeleteButton) { _showDeleteButton = false; } }); }, //处理滑动结束 onHorizontalDragEnd: (details) { if (_slideOffset > 30) { //用户左滑的距离大于30,则显示删除按钮 _slideOffset = _maxSlideDistance; } else { //否则就不显示删除按钮 _slideOffset = 0; _showDeleteButton = false; } setState(() {}); }, child: Transform.translate( //平移变换组件 //offset(dx,dy) //dx表示X轴偏移,dy表示Y轴偏移 //Offset(正数, 0) → 向右移动 ; Offset(负数, 0) → 向左移动 //Offset(10, 0)表示向右移动10像素 ; Offset(-10, 0)表示向左移动10像素 ;Offset(0, 0)表示不移动 offset: Offset(-_slideOffset, 0),//注意这里这里有个负号,所以这个小于零变成右移,大于零变成左移 child: Container( width: 320, height: 40, decoration: BoxDecoration( color: Color(0xFF1E2134), borderRadius: BorderRadius.circular(20), ), child: Center( child: Text( //通过是否显示删除按钮,来更新文本 _showDeleteButton ? "松手删除" : "向右滑动显示删除", style: TextStyle( color: Colors.white, fontSize: 16, ), ), ), ), ), ), ], ), ), ), ), ); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 12:00:03

为什么顶尖量子开发者都在用VSCode做远程调试?真相曝光

第一章&#xff1a;为什么顶尖量子开发者都在用VSCode做远程调试&#xff1f;在量子计算领域&#xff0c;开发环境的稳定性和调试效率直接影响算法实现的准确性与迭代速度。越来越多顶尖量子开发者选择 Visual Studio Code&#xff08;VSCode&#xff09;作为核心开发工具&…

作者头像 李华
网站建设 2026/8/20 20:18:19

Docker MCP 网关服务发现全攻略(从原理到实战的稀缺笔记)

第一章&#xff1a;Docker MCP 网关服务发现全解析在现代微服务架构中&#xff0c;Docker 容器化部署已成为主流实践。MCP&#xff08;Microservice Control Plane&#xff09;网关作为服务流量的统一入口&#xff0c;其服务发现机制直接影响系统的稳定性与可扩展性。Docker 环…

作者头像 李华
网站建设 2026/8/21 22:14:26

Arbess从基础到实践(6) - 集成GitLab搭建Vue.js项目自动化部署

Arbess 是一款开源免费的 CI/CD 工具&#xff0c;支持免费私有化部署&#xff0c;一键安装零配置&#xff0c;简洁易用等特点。本文将详细介绍如何安装Arbess、GitLab&#xff0c;并创建配置流水线实现 Vue.Js 项目构建并主机部署。 1、GitLab 安装与配置 本章节将介绍如何使…

作者头像 李华
网站建设 2026/8/21 23:26:34

League Akari:智能决策型英雄联盟辅助系统深度解析

玩家痛点矩阵&#xff1a;从繁琐操作到智能托管的进化之路 【免费下载链接】LeagueAkari ✨兴趣使然的&#xff0c;功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari 在英雄联盟的竞技…

作者头像 李华
网站建设 2026/8/20 21:46:10

万字长文解析润乾NLQ破局Text2SQL,兼得灵活复杂准确

自然语言转 SQL&#xff08;Text2SQL&#xff09;技术旨在降低数据查询的技术门槛&#xff0c;但一直面临 "灵活性"、"准确性" 与 "查询复杂性" 难以兼顾的困境。直接由大语言模型生成 SQL 存在语义 "幻觉" 造成准确性偏低&#xff0c…

作者头像 李华
网站建设 2026/8/21 18:03:34

ViGEmBus:Windows游戏控制器模拟技术深度解析

ViGEmBus&#xff1a;Windows游戏控制器模拟技术深度解析 【免费下载链接】ViGEmBus 项目地址: https://gitcode.com/gh_mirrors/vig/ViGEmBus ViGEmBus是一款专业的Windows内核模式驱动程序&#xff0c;专注于实现USB游戏控制器的精确模拟。作为Virtual Gamepad Emula…

作者头像 李华