企业网站建设客户需求调查问卷,网站设计 素材,crm营销,ps教程网站有哪些Flutter 代码如何实现了一个全局悬浮按钮#xff0c;当点击按钮时#xff0c;会显示一个可以拖动并且通过长按可以移除的悬浮控件。
前置知识点学习
Offset
Offset 是 Flutter 中的一个类#xff0c;用于表示二维平面中的位置或位移。它通常用于描述坐标系中的一个点当点击按钮时会显示一个可以拖动并且通过长按可以移除的悬浮控件。
前置知识点学习
Offset
Offset 是 Flutter 中的一个类用于表示二维平面中的位置或位移。它通常用于描述坐标系中的一个点或者用于指定某种移动的向量。Offset 是在 Flutter 的绘制和布局过程中非常常用的类尤其是在自定义绘制和触摸事件处理中。
构造函数
Offset(double dx, double dy):
dx: 在水平方向上的偏移量。
dy: 在垂直方向上的偏移量。
常用属性
dx: 水平方向的偏移量。
dy: 垂直方向的偏移量。
常用方法
distance: 返回从原点0, 0到这个偏移量的直线距离。
direction: 返回从原点到这个偏移量的角度以弧度为单位相对于水平方向。
scale(double scaleX, double scaleY): 返回一个新的 Offset其 dx 和 dy 分别乘以 scaleX 和 scaleY。
translate(double translateX, double translateY): 返回一个新的 Offset其 dx 和 dy 加上 translateX 和 translateY。 操作符重载
加法 (): 可以将两个 Offset 相加返回新的 Offset。
减法 (-): 可以将两个 Offset 相减返回新的 Offset。
乘法 (*): 可以将 Offset 与一个标量相乘返回新的 Offset。
除法 (/): 可以将 Offset 与一个标量相除返回新的 Offset。 示例
下面是一个简单的示例展示如何使用 Offset
import package:flutter/material.dart;class OffserExample extends StatelessWidget {const OffserExample({super.key});overrideWidget build(BuildContext context) {Offset offset1 const Offset(10.0, 20.0);Offset offset2 const Offset(5.0, 15.0);Offset result offset1 offset2; // Add two offsetsdouble distance result.distance; // Calculate distance from originreturn Scaffold(appBar: AppBar(title: const Text(Offset Example),),body: Center(child: Text(Resulting Offset: $result\nDistance from origin: $distance,textAlign: TextAlign.center,),),);}
}解释
在这个示例中offset1 和 offset2 是两个 Offset 实例。
通过 操作符我们将两个 Offset 相加得到一个新的 Offset。
distance 属性计算从原点到 result 的直线距离。 使用场景
自定义绘制: 在 Flutter 的 CustomPainter 中Offset 常用于指定绘制起点。
触摸事件: 在处理触摸事件时Offset 用于描述触摸点的位置。
布局计算: 在自定义布局逻辑中Offset 可以用于计算组件的位置和移动。 Overlay
Overlay 是 Flutter 中的一个强大组件用于在应用的普通界面层之上创建浮动层。它允许开发者在现有界面之上展示额外的内容比如弹出窗口、工具提示、悬浮按钮等。这种层叠效果是通过 OverlayEntry 来实现的。 主要特性
层叠显示: Overlay 可以将多个 OverlayEntry 叠加在一起形成一个层次结构最上面的条目会显示在最上层。
动态插入和移除: 可以在运行时动态添加或移除 OverlayEntry从而实现动态显示和隐藏界面元素。
灵活性: 可以在任何地方插入 OverlayEntry不受父组件的限制这给予了开发者极大的灵活性。
核心组件
1.Overlay:
Overlay 是一个用于管理和显示 OverlayEntry 的容器。通常在 MaterialApp 的根布局中已经存在一个 Overlay。
2.OverlayEntry:
OverlayEntry 是一个可以插入到 Overlay 中的条目。每个条目都可以独立控制其显示和隐藏。 使用步骤
1.获取 Overlay 的引用:
使用 Overlay.of(context) 来获得当前上下文的 Overlay 实例。
2.创建 OverlayEntry:
定义一个 OverlayEntry提供一个 builder 方法来返回要显示的 widget。
3.插入 OverlayEntry:
使用 Overlay.insert(overlayEntry) 方法将 OverlayEntry 插入到 Overlay 中。
4.移除 OverlayEntry:
调用 overlayEntry.remove() 方法来从 Overlay 中移除条目。 示例
以下是一个简单的示例展示如何使用 Overlay 来显示一个悬浮的红色圆形按钮
import package:flutter/material.dart;class OverlayExample extends StatefulWidget {const OverlayExample({super.key});override_OverlayExampleState createState() {return _OverlayExampleState();}
}class _OverlayExampleState extends StateOverlayExample {OverlayEntry? _overlayEntry;void _showOverlay(BuildContext context) {OverlayState overlayState Overlay.of(context);_overlayEntry OverlayEntry(builder: (context) Positioned(top: 100,left: 100,child: GestureDetector(onTap: () {_overlayEntry?.remove();},child: const CircleAvatar(radius: 50,backgroundColor: Colors.redAccent,child: Icon(Icons.close,color: Colors.white,),),)));overlayState.insert(_overlayEntry!);}overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(Overlay Example),),body: Center(child: ElevatedButton(onPressed: () _showOverlay(context),child: const Text(Show Overlay),),),);}
}解释
OverlayEntry:
创建了一个 OverlayEntry它包含一个 Positioned widget用于定位其位置。
包含一个 GestureDetector用来监听点击事件点击后移除该 OverlayEntry。 展示和移除:
点击按钮调用 _showOverlay 方法将 OverlayEntry 插入到 Overlay 中。
GestureDetector 侦听点击事件。当用户点击红色圆形按钮时调用 _overlayEntry?.remove() 将其从 Overlay 中移除。 使用场景
浮动按钮: 实现全局悬浮按钮用户可以在任何页面上访问。
弹出窗口: 创建自定义的弹出窗口或对话框而不需要中断当前页面的布局。
工具提示: 在特定的 UI 元素上方显示工具提示或帮助信息。
通知: 实现临时通知或警告显示在应用的顶部或底部。
注意事项
层叠顺序: OverlayEntry 是按插入顺序堆叠的后插入的条目会显示在前面的条目之上。
管理条目: 在使用 OverlayEntry 时确保正确管理其生命周期避免内存泄漏。例如及时调用 remove() 方法移除不再需要的条目。
性能考虑: 虽然 Overlay 提供了灵活的 UI 设计但在频繁更新或大量使用时可能会影响性能。因此合理使用 Overlay 以保持应用的流畅性。
通过 Overlay 和 OverlayEntryFlutter 提供了强大的工具来创建灵活的 UI 组件允许在不干扰现有布局的情况下实现复杂的用户交互。 GestureDetector
GestureDetector 是 Flutter 中用于检测手势的一个小部件。它可以包裹其他小部件并通过监听用户的手势来响应触摸事件。GestureDetector 提供了多种手势回调函数允许开发者处理点击、双击、长按、拖动、缩放等手势。 主要属性
GestureDetector 提供了多种手势检测回调以下是一些常用的属性
onTap: 当用户轻触屏幕时触发。
onDoubleTap: 当用户快速连续点击两次时触发。
onLongPress: 当用户长时间按住屏幕时触发。
onPanUpdate: 当用户在屏幕上拖动时触发每次拖动位置变化时都会调用。
onPanStart: 当用户开始拖动时触发。
onPanEnd: 当用户结束拖动时触发。
onScaleUpdate: 当用户执行缩放手势时触发。
onVerticalDragUpdate: 当用户在垂直方向上拖动时触发。
onHorizontalDragUpdate: 当用户在水平方向上拖动时触发。 使用示例
以下是一个简单的示例展示如何使用 GestureDetector 处理点击和拖动手势
import package:flutter/material.dart;class GestureDetectorExample2 extends StatefulWidget {const GestureDetectorExample2({super.key});override_GestureDetectorExampleState2 createState() {return _GestureDetectorExampleState2();}
}class _GestureDetectorExampleState2 extends StateGestureDetectorExample2 {Color _color Colors.blueGrey;Offset _offset const Offset(100, 100);overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(GestureDetector Example),),body: Stack(children: [Positioned(left: _offset.dx,top: _offset.dy,child: GestureDetector(onTap: () {setState(() {_color _color Colors.blue ? Colors.red : Colors.blue;});},onPanUpdate: (details) {setState(() {_offset details.delta;});},child: Container(width: 100,height: 100,color: _color,child: const Center(child: Text(Tap or Drag,style: TextStyle(color: Colors.white),),),),))],),);}
}解释
GestureDetector: 包裹了一个 Container用于检测点击和拖动手势。
onTap 回调: 每次点击 Container 时切换颜色。
onPanUpdate 回调: 每次拖动时更新 _offset从而移动 Container 的位置。
Positioned: 用于根据 _offset 的值定位 Container从而实现拖动效果。
使用场景
交互元素: 为按钮、图标或任何可交互元素添加手势响应。
自定义手势: 在自定义组件中实现复杂的手势交互如拖放、缩放等。
游戏开发: 在游戏中检测用户的触摸和拖动以实现交互。 Material
Material 是 Flutter 提供的一个核心组件它实现了 Material Design 的视觉效果和行为规范。Material 小部件是许多 Flutter UI 组件的基础比如按钮、卡片、对话框等这些组件都依赖于 Material 来提供背景、阴影、剪裁等效果。 主要功能
背景颜色: Material 提供了背景颜色可以是单一颜色或者是渐变。
阴影: 通过 elevation 属性Material 可以在其下方投射阴影营造出悬浮的效果。
剪裁: 通过 shape 属性可以将 Material 剪裁成特定的形状如圆形、矩形、圆角矩形等。
触觉反馈: 在交互时Material 提供了触觉反馈比如波纹效果InkWell。 主要属性
color: 设置 Material 的背景颜色。
elevation: 控制阴影的深度值越大阴影越明显。
shape: 定义 Material 的形状可以是 RoundedRectangleBorder、CircleBorder 等。
borderRadius: 如果形状是矩形可以通过这个属性设置圆角。
type: 指定 Material 的类型MaterialType.canvas 表示没有阴影的背景MaterialType.card 表示有阴影的卡片。
示例
以下是一个简单的示例展示如何使用 Material
import package:flutter/material.dart;class MaterialExample extends StatelessWidget {const MaterialExample({super.key});overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(Material Example),),body: Center(child: Material(color: Colors.blueGrey,elevation: 5.0,borderRadius: BorderRadius.circular(10.0),child: Container(width: 200,height: 100,alignment: Alignment.center,child: const Text(Hello, Material!,style: TextStyle(color: Colors.white, fontSize: 18),),),),),);}
}解释
Material: 包裹了一个 Container提供背景颜色、阴影和圆角效果。
elevation: 设置为 5.0创建了一个轻微的阴影效果。
borderRadius: 通过 BorderRadius.circular() 设置圆角从而使 Material 的背景具有圆角效果。
color: 设置为蓝色使得 Material 的背景为蓝色。 使用场景
卡片和面板: Material 常用于实现卡片、面板等带有阴影和圆角的组件。
自定义按钮: 通过组合 Material 和 InkWell可以创建自定义的按钮效果。
对话框和弹出窗口: Material 提供了基础的视觉效果是实现对话框、弹出窗口的基础。 注意事项
性能: elevation 属性会增加阴影计算因此在性能敏感的环境中应谨慎使用高阴影值。
触摸效果: 需要与 InkWell 或 InkResponse 结合使用才能实现点击时的波纹效果。 BoxDecoration
BoxDecoration 是 Flutter 中用于装饰容器如 Container的一个类。它允许开发者为容器添加背景颜色、图像、边框、阴影和渐变等多种视觉效果。BoxDecoration 是一个强大的工具能够帮助你实现复杂的 UI 样式。 主要属性
BoxDecoration 提供了多种属性以定义容器的装饰效果
color: 背景颜色。设置容器的背景色。
image: 背景图像。通过 DecorationImage 设置背景图像及其位置、重复方式等。
border: 边框。通过 Border 类设置容器的边框可以指定每边的宽度和颜色。
borderRadius: 圆角边框半径。常用于给矩形容器添加圆角。
boxShadow: 阴影效果。通过 BoxShadow 类定义阴影的颜色、偏移量、模糊半径和扩展半径。
gradient: 渐变效果。可以是线性渐变LinearGradient或径向渐变RadialGradient。
shape: 形状。可以是 BoxShape.rectangle默认或 BoxShape.circle。 使用示例
以下是一个简单的示例展示如何使用 BoxDecoration 来装饰一个 Container
import package:flutter/material.dart;class BoxDecorationExample22 extends StatelessWidget {const BoxDecorationExample22({super.key});overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(BoxDecoration Example),),body: Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(20),border: Border.all(color: Colors.black, width: 3),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5),offset: const Offset(2, 2),blurRadius: 5)],gradient: const LinearGradient(colors: [Colors.blue, Colors.lightBlueAccent],begin: Alignment.topLeft,end: Alignment.bottomRight),),child: const Text(Hello, BoxDecoration!,style: TextStyle(color: Colors.white, fontSize: 16),textAlign: TextAlign.center,),),),);}
}解释
Container: 使用 BoxDecoration 来装饰。
color: 设置容器的背景颜色为蓝色。
borderRadius: 通过 BorderRadius.circular(20) 实现圆角效果。
border: 添加一个黑色边框宽度为 3。
boxShadow: 添加一个半透明的黑色阴影偏移量为 (2, 2)模糊半径为 5。
gradient: 使用线性渐变从蓝色到浅蓝色。
使用场景
卡片样式: 为 UI 卡片提供复杂的视觉效果包括阴影、圆角和渐变。
背景装饰: 为布局元素添加背景图像、颜色和渐变。 TextButton
TextButton 是 Flutter 中的一种按钮组件是 Material Design 提供的按钮类型之一。它是一种扁平的按钮通常用于没有明显边框或阴影的场合。TextButton 是 FlatButton 的替代品FlatButton 在 Flutter 的较早版本中被使用但在现代 Flutter 中被 TextButton 所取代。 主要属性
onPressed: 一个回调函数当按钮被点击时调用。如果此属性为 null按钮将被禁用通常会变灰。
child: 按钮的内容通常是一个 Text 小部件但也可以是其他小部件如 Icon 或 Row。
style: 用于自定义按钮的外观包括文本样式、按钮背景颜色、形状、边距等。 使用示例
以下是如何使用 TextButton 的简单示例
import package:flutter/material.dart;class TextButtonExample22 extends StatelessWidget {const TextButtonExample22({super.key});overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(TextButton Example),),body: Center(child: TextButton(onPressed: () {print(TextButton pressed!);},style: TextButton.styleFrom(foregroundColor: Colors.white,backgroundColor: Colors.blue,padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10),),),child: const Text(Click),),),);}
}解释
onPressed: 这是一个必需的属性用于指定按钮按下时的行为。在示例中它简单地打印了一条消息。
style: 使用 TextButton.styleFrom 来定义按钮的样式。
primary: 文本颜色。
backgroundColor: 按钮背景颜色。
padding: 定义按钮内边距。
shape: 定义按钮的形状这里使用 RoundedRectangleBorder 来创建圆角矩形。
child: 按钮的内容这里是一个 Text 小部件显示按钮文本。
使用场景
表单提交: 用于表单中的提交按钮等。
导航: 实现简单的页面导航或动作触发。
扁平风格设计: 在需要满足 Material Design 扁平设计风格的应用中使用。
其他注意事项
禁用状态: 如果 onPressed 设置为 null按钮将被禁用可以通过样式调整按钮在禁用状态下的外观。
替代品: 与 ElevatedButton 和 OutlinedButton 一起TextButton 是 Flutter 提供的三种主要按钮之一。它适用于不需要突出显示的按钮场景。
通过使用 TextButton你可以轻松创建符合 Material Design 的现代、简洁的按钮。其灵活的样式系统允许你根据特定的设计需求自定义按钮的外观和行为。 flutter实现全局悬浮按钮代码学习
import package:flutter/material.dart;class FloatingTouchDemoPage22 extends StatefulWidget {const FloatingTouchDemoPage22({super.key});override_FloatingTouchDemoPageState22 createState() {return _FloatingTouchDemoPageState22();}
}class _FloatingTouchDemoPageState22 extends StateFloatingTouchDemoPage22 {Offset offset const Offset(200, 200);final double height 80;_showFloating() {var overlayState Overlay.of(context);OverlayEntry? overlayEntry;overlayEntry OverlayEntry(builder: (context) {return Stack(children: Widget[Positioned(left: offset.dx,top: offset.dy,child: _buildFloating(overlayEntry),)],);});overlayState.insert(overlayEntry);}_buildFloating(OverlayEntry? overlayEntry) {return GestureDetector(behavior: HitTestBehavior.deferToChild,onPanDown: (details) {offset details.globalPosition - Offset(height / 2, height / 2);overlayEntry!.markNeedsBuild();},onPanUpdate: (DragUpdateDetails details) {offset offset details.delta;overlayEntry!.markNeedsBuild();},onLongPress: () {overlayEntry!.remove();},child: Material(color: Colors.transparent,child: Container(height: height,width: height,alignment: Alignment.center,decoration: BoxDecoration(color: Colors.redAccent,borderRadius: BorderRadius.all(Radius.circular(height / 2))),child: const Text(长按\n移除,style: TextStyle(color: Colors.white),),),),);}overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(FloatingTouchDemoPage),),body: Center(child: TextButton(onPressed: () {_showFloating();},child: const Text(show floating button),),),);}
}