Flutter 04 按钮Button和事件处理、弹框Dialog、Toast

一、按钮组件

1、按钮类型:

2、按钮实现效果:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const LayoutDemo(),),);}
}class LayoutDemo extends StatelessWidget {const LayoutDemo({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return ListView(children: [Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton(onPressed: () {print("ElevatedButton....");},child: const Text("普通按钮")),TextButton(onPressed: () {}, child: const Text("文本按钮")),OutlinedButton(onPressed: () {}, child: const Text("边框按钮")),IconButton(onPressed: () {}, icon: const Icon(Icons.thumb_up))],),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ElevatedButton.icon(onPressed: () {},icon: const Icon(Icons.send),label: const Text("发送")),TextButton.icon(onPressed: () {},icon: const Icon(Icons.info),label: const Text("消息")),OutlinedButton.icon(onPressed: null,icon: const Icon(Icons.add),label: const Text("增加"))]),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ElevatedButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red), //背景颜色foregroundColor:MaterialStateProperty.all(Colors.white) //文字图标颜色),onPressed: () {print("ElevatedButton");},child: const Text("普通按钮")),]),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [Container(height: 60,width: 140,child: ElevatedButton(onPressed: () {},child: const Text("大按钮"),),),SizedBox(height: 40,width: 100,child: ElevatedButton.icon(onPressed: () {},icon: const Icon(Icons.search),label: const Text("搜索"),),)],),const SizedBox(height: 20,),Row(children: [Expanded(flex: 1,child: Container(margin: const EdgeInsets.all(20),height: 50,child: ElevatedButton(onPressed: () {},style: ButtonStyle(backgroundColor: MaterialStateProperty.all(const Color.fromARGB(220, 245, 71, 71)),foregroundColor:MaterialStateProperty.all(Colors.white)),child: const Text("登录"),),))],),const SizedBox(height: 20,),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [ElevatedButton(style: ButtonStyle(shape: MaterialStateProperty.all(//圆角RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)))),onPressed: () {},child: const Text("圆角")),SizedBox(height: 80,width: 80,child: ElevatedButton(style: ButtonStyle(shape: MaterialStateProperty.all(//圆形const CircleBorder(side:BorderSide(width: 2, color: Colors.yellow)))),onPressed: () {},child: const Text("圆形")),),],),const SizedBox(height: 20),Row(mainAxisAlignment: MainAxisAlignment.center,children: [OutlinedButton(style: ButtonStyle(side: MaterialStateProperty.all(//修改边框颜色const BorderSide(width: 1, color: Colors.red))),onPressed: () {},child: const Text("带边框的按钮"))],)],);}
}

二、事件处理

1、在Flutter中,手势有两个不同的层次:

第一层:原始指针事件(Pointer Events):描述了屏幕上由触摸板、鼠标、指示笔等触发的指针的位置和移动。

第二层:手势识别(Gesture Detector):这个是在原始事件上的一种封装。

2、指针事件Pointer:

demo:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: MyHomePage(),),);}
}//事件基本应用,指针事件(Touch)
class MyHomePage extends StatelessWidget {const MyHomePage({super.key});@overrideWidget build(BuildContext context) {return Center(child: Listener(child: Container(width: 200,height: 200,color: Colors.red,// child:  ElevatedButton(//     onPressed: () {//       print("ElevatedButton....");//     },//     child: const Text("普通按钮")),),onPointerDown: (event) => print("手指按下,当前位置,全局:${event.position}|控件内:${event.localPosition}"),onPointerMove: (event) => print("手指移动:$event"),onPointerUp: (event) => print("手指抬起:$event"),),);}
}

3、手势识别(Gesture Detector):

1)GestureDetector封装了点击、双击、滑动等大量功能,使开发者可以快速使用这些基础性功能:
GestureDetector({super.key,this.child,this.onTapDown,this.onTapUp,this.onTap,this.onTapCancel,this.onSecondaryTap,this.onSecondaryTapDown,this.onSecondaryTapUp,this.onSecondaryTapCancel,this.onTertiaryTapDown,this.onTertiaryTapUp,this.onTertiaryTapCancel,this.onDoubleTapDown,this.onDoubleTap,this.onDoubleTapCancel,this.onLongPressDown,this.onLongPressCancel,this.onLongPress,this.onLongPressStart,this.onLongPressMoveUpdate,this.onLongPressUp,this.onLongPressEnd,this.onSecondaryLongPressDown,this.onSecondaryLongPressCancel,this.onSecondaryLongPress,this.onSecondaryLongPressStart,this.onSecondaryLongPressMoveUpdate,this.onSecondaryLongPressUp,this.onSecondaryLongPressEnd,this.onTertiaryLongPressDown,this.onTertiaryLongPressCancel,this.onTertiaryLongPress,this.onTertiaryLongPressStart,this.onTertiaryLongPressMoveUpdate,this.onTertiaryLongPressUp,this.onTertiaryLongPressEnd,this.onVerticalDragDown,this.onVerticalDragStart,this.onVerticalDragUpdate,this.onVerticalDragEnd,this.onVerticalDragCancel,this.onHorizontalDragDown,this.onHorizontalDragStart,this.onHorizontalDragUpdate,this.onHorizontalDragEnd,this.onHorizontalDragCancel,this.onForcePressStart,this.onForcePressPeak,this.onForcePressUpdate,this.onForcePressEnd,this.onPanDown,this.onPanStart,this.onPanUpdate,this.onPanEnd,this.onPanCancel,this.onScaleStart,this.onScaleUpdate,this.onScaleEnd,this.behavior,this.excludeFromSemantics = false,this.dragStartBehavior = DragStartBehavior.start,})
2)Gesture种类非常多:

3)事件拦截应用:

可以通过Stack布局来解决手势冲突,避免嵌套。

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: MyHomePage(),),);}
}class MyHomePage extends StatelessWidget {_onPointerDown(PointerDownEvent event) {if (kDebugMode) {print("_onPointerDown:$event");}}_onPointerMove(PointerMoveEvent event) {if (kDebugMode) {print("_onPointerMove:$event");}}_onPointerUp(PointerUpEvent event) {if (kDebugMode) {print("_onPointerUp:$event");}}_onPointerEnter(PointerEnterEvent event) {if (kDebugMode) {print("_onPointerEnter:$event");}}_onPointerExit(PointerCancelEvent event) {if (kDebugMode) {print("_onPointerExit:$event");}}_onPointerHover(PointerHoverEvent event) {if (kDebugMode) {print("_onPointerHover:$event");}}_onPointerDown1(PointerDownEvent event) {if (kDebugMode) {print("_onPointerDown1:$event");}}_onPointerMove1(PointerMoveEvent event) {if (kDebugMode) {print("_onPointerMove1:$event");}}_onPointerUp1(PointerUpEvent event) {if (kDebugMode) {print("_onPointerUp1:$event");}}@overrideWidget build(BuildContext context) {return Listener(onPointerDown: _onPointerDown,onPointerMove: _onPointerMove,onPointerUp: _onPointerUp,onPointerCancel: _onPointerExit,onPointerHover: _onPointerHover,child: Stack(children: <Widget>[GestureDetector(//监听点击事件onTap: () => {print("点击事件")},//监听横向滑动事件onVerticalDragUpdate: (DragUpdateDetails details) => {print("横向滑动:$details")},child: Listener(onPointerDown: _onPointerDown1,onPointerMove: _onPointerMove1,onPointerUp: _onPointerUp1,child: Center(child: Container(color: Colors.red,width: 200.0,height: 100.0,),)),),],));}
}

三、弹框组件Dialog

Dialog页面代码:

import 'package:flutter/material.dart';
import 'dialog/MyToast.dart';import 'dialog/dialog.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const LayoutDemo(),),);}
}class LayoutDemo extends StatelessWidget {const LayoutDemo({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: () async{var result = await alertDialog(context);print(result);},child: const Text('alert弹出框-AlertDialog '),),const SizedBox(height: 20),ElevatedButton(onPressed: () async{var result = modelBottomSheet(context);print("result:$result");},child: const Text('select弹出框-SimpleDialog'),),const SizedBox(height: 20),ElevatedButton(onPressed: () async{var result = await showDialog(barrierDismissible: true, //表示点击灰色背景的时候是否消失弹出框 context: context,builder: (context) {return MyDialog(title: '标题',onClosed: () {print("关闭");Navigator.of(context).pop();},content: "我是一个内容");}, context: context);print("result:$result");},child: const Text('自定义dialog'),),const SizedBox(height: 20),ElevatedButton(onPressed: () async{var result = await simpleDialog(context);print("result:$result");},child: const Text('ActionSheet底部弹出框'),),const SizedBox(height: 20),ElevatedButton(onPressed: (){// Fluttertoast.showToast(//     msg: "提示信息",////     toastLength: Toast.LENGTH_LONG,   //值针对 android 平台//     timeInSecForIosWeb: 1,  //提示时间 针对ios 和 web//     backgroundColor: Colors.black26, //背景颜色//     textColor: Colors.white,   //文本颜色//     fontSize: 16.0  //文本字体大小// );Toast.showInfo("message", context: context, duration: 2000);},child: const Text('Toast'),),// fluttertoast],),);}
}

1、AlertDialog:

最简单的方案是利用AlertDialog组件构建一个弹框

import 'package:flutter/material.dart';Object alertDialog(BuildContext context) async {var result = await showDialog(barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框context: context,builder: (context) {return AlertDialog(title: const Text("提示信息!"),content: const Text("您确定要删除吗"),actions: [TextButton(onPressed: () {print("ok");Navigator.of(context).pop("ok"); //点击按钮让AlertDialog消失},child: const Text("确定")),TextButton(onPressed: () {print("cancel");Navigator.of(context).pop("取消");},child: const Text("取消"))],);});return result;
}

 2、SimpleDialog:

通过SimpleDialog构建一个选择框

import 'package:flutter/material.dart';Object simpleDialog(BuildContext context) async {var result = await showDialog(barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框context: context,builder: (context) {return SimpleDialog(title: const Text("请选择语言"),children: [SimpleDialogOption(onPressed: () {print("汉语");Navigator.pop(context, "汉语");},child: const Text("汉语"),),const Divider(),SimpleDialogOption(onPressed: () {print("英语");Navigator.pop(context, "英语");},child: const Text("英语"),),const Divider(),SimpleDialogOption(onPressed: () {print("日语");Navigator.pop(context, "日语");},child: const Text("日语"),),const Divider(),],);});return result;
}

3、showModalBottomSheet:

通过showModalBottomSheet构建一个底部弹框

 

import 'package:flutter/material.dart';Object modelBottomSheet(BuildContext context) {return showModalBottomSheet(context: context,builder: (context) {return SizedBox(height: 240,child: Column(crossAxisAlignment: CrossAxisAlignment.center,children: [ListTile(title: const Text("分享"),onTap: () {print("分享");Navigator.of(context).pop("分享");},),const Divider(),ListTile(title: const Text("收藏"),onTap: () {print("收藏");Navigator.of(context).pop("收藏");},),const Divider(),ListTile(title: const Text("取消"),onTap: () {print("取消");Navigator.of(context).pop("取消");},),const Divider(),],),);});
}

4、自定义Flutter Dialog:

import 'package:flutter/material.dart';// 自定义dialog
class MyDialog extends Dialog {String title;String content;Function()? onClosed;MyDialog({Key? key, required this.title,requiredthis.onClosed,this.content=""}) : super(key: key);@overrideWidget build(BuildContext context) {return Material(type: MaterialType.transparency,child: Center(child: Container(height: 300,width: 300,color: Colors.white,child: Column(children: <Widget>[Padding(padding: const EdgeInsets.all(10),child: Stack(children: <Widget>[Align(alignment: Alignment.center,child: Text(title),),Align(alignment: Alignment.centerRight,child: InkWell(onTap: onClosed,child: const Icon(Icons.close),),)],),),const Divider(),Container(padding: const EdgeInsets.all(10),width: double.infinity,child: Text(content,textAlign: TextAlign.left),)],),)),);}
}

四、Toast

所谓toast框其实就是在图层的最上面一层插入一个显示图层,在Flutter中利用OverLayEntry构建图层,然后通过Overlay进行插入。

1、自定义Toast:

import 'package:flutter/material.dart';class Toast {static var _lastMsg;static int _lastShowms = 0;static Future _show(BuildContext context, String msg, int duration) {OverlayEntry entry = OverlayEntry(builder: (BuildContext context) => Positioned(//top值,可以改变这个值来改变toast在屏幕中的位置top: MediaQuery.of(context).size.height.toDouble() * 0.5,child: Container(alignment: Alignment.center,width: MediaQuery.of(context).size.width,child: Padding(padding: const EdgeInsets.symmetric(horizontal: 10.0),child: _buildToastWidget(context, msg),)),));///往Overlay中插入插入OverlayEntryOverlay.of(context)?.insert(entry);///两秒后,移除ToastFuture result = Future.delayed(Duration(milliseconds: duration)).then((value) {entry.remove();});return result;}//toast UI绘制static _buildToastWidget(context, String msg) {return Row(mainAxisSize: MainAxisSize.min,children: [Container(alignment: Alignment.center,decoration: BoxDecoration(borderRadius: BorderRadius.circular(12.0),shape: BoxShape.rectangle,color: Colors.black45,),child: Padding(padding: const EdgeInsets.all(10),child: Text(msg,style: const TextStyle(color: Colors.white,decoration: TextDecoration.none,fontSize: 14)),))],);}//处理重复多次点击static void _handleDuplicateAndShow(String message, BuildContext context, int duration) {if (_lastMsg == message) {//相同信息内容int currentms = DateTime.now().millisecondsSinceEpoch;int interval = currentms - _lastShowms;if (interval > duration) {//大于时间间隔 可以显示_show(context, message, duration);_lastShowms = currentms;}} else {_show(context, message, duration);_lastMsg = message;}}/// 提示static void showInfo(String message, {required BuildContext context, int duration = 2000}) {_handleDuplicateAndShow(message, context, duration);}
}

2、使用第三方框架(fluttertoast):

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

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

相关文章

python爬虫—使用xpath方法进行数据解析

1. 背景信息 爬取安居客二手房源信息 URL地址&#xff1a;https://wuhan.anjuke.com/sale/?fromnavigation 2. 代码实现 import requests from lxml import etreeif __name__ __main__:# 1.指定URLurl "https://wuhan.anjuke.com/sale/?fromnavigation"# 2.U…

Vue 项目中如何使用Bootstrap5(简单易懂)

Vue 项目中如何使用Bootstrap5&#xff08;简单易懂&#xff09; 安装在 src/main.js 文件下引入包在vue文件中使用 Bootstrap官网&#xff08;中文&#xff09;&#xff1a;https://www.bootcss.com/ Bootstrap5文档&#xff1a;https://v5.bootcss.com/docs/getting-started/…

40 深度学习(四):卷积神经网络|深度可分离卷积|colab和kaggle的基础使用

文章目录 卷积神经网络为什么要卷积卷积的具体流程池化tensorflow代码 深度可分离卷积原理介绍计算量对比代码参数计算例子 colab 和 kagglecolabkaggle如何在colab上使用kaggle的数据 卷积神经网络 卷积神经网络的基本结构 1&#xff1a; (卷积层(可选)池化层) * N全连接层 *…

java版直播商城平台规划及常见的营销模式 电商源码/小程序/三级分销+商城免费搭建

营销模式 通用版本&#xff08;标准多商户入驻二级分销体系满减、满送、优惠券、组合销售、平台礼包等营销活动&#xff09; 直播、短视频带货版本&#xff08;标准多商户入驻直播、短视频带货二级分销体系满减、满送、优惠券、组合销售、平台礼包等营销活动&#xff09; 特殊营…

跨境电商大作战:2023黑色星期五准备指南

黑色星期五&#xff0c;作为全球购物狂欢的象征&#xff0c;已经成为了电商业务的一年一度的重要节点。尤其对于跨境电商来说&#xff0c;这一天意味着巨大的商机和挑战。为了在这个竞争激烈的时刻脱颖而出&#xff0c;跨境电商必须做好充分的准备。Nox聚星在这里给大家分享几个…

Vue elemen ui 移除上次校验与部分清除上次校验

场景&#xff1a; 可以切换类型&#xff0c;下面的输入框参数也会随着改变。 如果不清除上次的校验就会出现&#xff0c;之前的大陆企业的校验还会出现在香港企业的校验中 方法&#xff1a; watch:{ruleForm.paymentSubjectType:{ 通过监听表单的类型来调用 clearValidate方…

耳朵小戴什么耳机合适,2023年适合小耳道的蓝牙无线耳机分享

你们是否曾为了追求音乐的同时&#xff0c;担心自己的听力健康呢&#xff1f;尤其是耳朵小的群体&#xff0c;佩戴入耳式时间一长&#xff0c;就会感觉耳道存在一定的疼痛感&#xff0c;不过别担心&#xff0c;现在有了一种完美的解决方案——骨传导耳机&#xff01;这种炫酷的…

windows版本redis如何设置后踢启动和重启计算机之后自动重启redis

1. 进入redis安装目录 D:\softwarePackage\redis\Redis-x64-3.2.100 2. 打开dos窗口 使用以下命令来启动 Redis 服务器&#xff0c;并使其在后台运行 redis-server --service-start 3. 设置重启自启动 打开服务界面 &#xff08;windowsr 输入 services.msc&#xff09; 找…

英飞凌TC3xx-Overlay

目录 1.数据访问重定向 2.寄存器说明 3.Overlay功能配置 3.1 确认用于重定向的CPU 3.2 配置重定向Block大小 3.3 配置目标地址和重定向地址 4.结果验证 5.小结 今天说要开个专栏讲讲XCP标定&#xff0c;但在将标定之前&#xff0c;先把英飞凌专门为标定功能设计overlay…

redis基础语法

redis数据特性与常用数据类型 redis的数据都是以字符串形式存储&#xff0c;以键值对形式存在的。其数据为二进制安全的&#xff0c;所以默认不支持中文。且注意&#xff0c;其键是区分大小写的。 Redis存储的是key-value结构的数据&#xff0c;其中key是字符串类型&#xff…

pycharm更改远程服务器地址

一、问题描述 在运行一些项目时&#xff0c;我们常需要在pycharm中连接远程服务器&#xff0c;但万一远程服务器的ip发生了变化&#xff0c;该如何修改呢&#xff1f;我们在file-settings-python interpreter中找到远程服务器&#xff0c;但是发现ip是灰色的&#xff0c;没有办…

食品企业数字孪生可视化管理平台,实现智慧轻工业高质量发展

如今&#xff0c;数字技术正在打破传统食品产业的边界&#xff0c;随着食品加工产业链不断进化为智慧体&#xff0c;数字孪生技术已经成了食品行业数字进阶的重要抓手。食品加工数字孪生工厂&#xff0c;通过应用数字孪生技术&#xff0c;将食品加工工厂的自动化生产线全过程进…