设计给的效果如下:

拿到设计后,先把整体拆分成几个部分:

  1. “可点击框”,使用堆栈(Stack)组件布局的可点击区域。
  2. “底部矩形”,用来衬托“主要矩形”,以形成立体效果的矩形。
  3. “主要矩形”,按钮主体部分,通过调整上下位置来模拟按压效果。

然后就可以开始进行编码了。

第1步:绘制组件树

第2步:实现“可点击框”

通过手势探测器(GestureDetector)组件,你可以通过检测多种手势并设置对应的处理函数。通过大小框(SizedBox)组件为“按钮”设置一个活动区域,并将堆栈(Stack)组件作为子组件置于其中。同时,通过activationonTapCallback两个变量来传递状态和回调函数。

import 'package:flutter/material.dart';/// 自定义的涂鸦按钮组件。
class DoodleButton extends StatefulWidget {// TODO: 第3步:实现“底部矩形”,成员变量。// TODO: 第4步:实现“主要矩形”,成员变量。/// 按钮的激活状态,默认为`false`。final bool activation;/// 发生点击时的回调函数。final Function onTapCallback;DoodleButton({// TODO: 第3步:实现“底部矩形”,默认构造。// TODO: 第4步:实现“主要矩形”,默认构造。this.activation: false,this.onTapCallback,});@override_DoodleButtonState createState() => _DoodleButtonState();
}/// 与自定义的涂鸦按钮组件关联的状态子类。
class _DoodleButtonState extends State<DoodleButton> {// TODO: 第4步:实现“主要矩形”,控制按压。@overrideWidget build(BuildContext context) {// 手势探测器(`GestureDetector`)组件,检测手势的组件。// 尝试识别与其非空回调相对应的手势。如果此组件具有子项,// 则它会根据其大小调整行为推迟该子项。// 如果它没有子组件,它会变得适合父组件。return GestureDetector(// 在点击(`onTap`)属性,发生了点击。onTap: widget.activation ? () {setState(() {// TODO: 第4步:实现“主要矩形”,“按下”按钮。widget.onTapCallback();// TODO: 第4步:实现“主要矩形”,“松开”按钮。});} : null,child: SizedBox(height: 48.0,// 堆栈(`Stack`)组件,用于将其子级相对于其框的边缘定位。child: Stack(children: <Widget>[// TODO: 第3步:实现“底部矩形”,实现容器。// TODO: 第4步:实现“主要矩形”,实现容器。]),),);}
}

第3步:实现“底部矩形”

通过backgroundColorsilentBackgroundColor变量来传递“按钮”可用、不可用时,“底部矩形”的颜色。

  // TODO: 第3步:实现“底部矩形”,成员变量。/// 按钮的底部颜色,默认为`#D95636`。final Color backgroundColor;/// 不可用按钮的底部颜色,默认为`#8A8A8A`。final Color silentBackgroundColor;// TODO: 第3步:实现“底部矩形”,默认构造。this.backgroundColor: const Color(0xFFD95636),this.silentBackgroundColor: const Color(0xFF8A8A8A),

使用对齐(Align)组件,并通过Alignment.bottomCenter将其设置为靠近下方对齐。再用边界半径(BorderRadius)类,将矩形的4个边角设置为圆角。

            // TODO: 第3步:实现“底部矩形”,实现容器。// 对齐(`Align`)组件,用于将其子项与其自身对齐,并根据子级的大小自行调整大小。Align(// 对准属性,如何调整子组件。alignment: Alignment.bottomCenter,child: Container(decoration: BoxDecoration(color: widget.activation ? widget.backgroundColor : widget.silentBackgroundColor,// 框装饰(`BoxDecoration`)类的边界(`border`)属性,在背景颜色、渐变或图像上方绘制的边框。// 边界(`Border`)类,框的边框,由四个边组成:顶部、右侧、底部、左侧。border: Border.all(// 宽度参数,边框的宽度。width: 2.0,// 颜色参数,边框的颜色。color: const Color(0xFF282828),),// 边界半径(`borderRadius`)属性,如果为非空值,则此属性将对此框的角进行舍入。// 边界半径(`BorderRadius`)类,矩形每个角的一组不可变半径。// 边界半径.所有(`BorderRadius.all`)构造函数,创建一个边界半径,设置所有的半径。borderRadius: BorderRadius.all(// 半径(`Radius`)类,圆形或椭圆形的半径。// 半径.圆(`Radius.circular`)构造函数,构造一个圆形半径,x和y将具有相同的半径值。Radius.circular(2.0),),),height: 42.0,),),

第4步:实现“主要矩形”

通过mainColorsilentMainColor变量来传递“按钮”可用、不可用时,“底部矩形”的颜色,promptText变量传递“按钮”的操作提示文本。

  // TODO: 第4步:实现“主要矩形”,成员变量。/// 按钮的操作提示文本。final String promptText;/// 按钮的主要颜色,默认为`#FF6B47`。final Color mainColor;/// 不可用按钮的主要颜色,默认为`#B2B2B2`。final Color silentMainColor;// TODO: 第4步:实现“主要矩形”,默认构造。this.promptText,this.mainColor: const Color(0xFFFF6B47),this.silentMainColor: const Color(0xFFB2B2B2),

通过对准(Alignment)类来控制“主要矩形”的按压效果:靠近上边时是松开按钮;靠近下边时是按下按钮。

  // TODO: 第4步:实现“主要矩形”,控制按压。// 对准(`Alignment`)类,矩形内的一个点。// [0.0,0.0]表示矩形的中心,[-1.0到+1.0]的距离是从矩形的一边到矩形的另一边的距离。// 因此,水平(或垂直)[2.0]单位等于矩形的宽度(或高度)。/// 主要容器的对齐方式,控制按钮的按压状态。Alignment mainContainerAlignment = Alignment.topCenter;// TODO: 第4步:实现“主要矩形”,“按下”按钮。mainContainerAlignment = Alignment.bottomCenter;widget.onTapCallback();// TODO: 第4步:实现“主要矩形”,“松开”按钮。mainContainerAlignment = Alignment.topCenter;

最后实现“主要矩形”的布局代码。

            // TODO: 第4步:实现“主要矩形”,实现容器。Align(alignment: mainContainerAlignment,child: Container(child: Center(child: Text(widget.promptText,style: TextStyle(color: const Color(0xFF282828),fontSize: 18.0,// 字体重量(`FontWeight`)类,用于绘制文本的字形的粗细。fontWeight: FontWeight.bold,),),),decoration: BoxDecoration(color: widget.activation ? widget.mainColor : widget.silentMainColor,border: Border.all(width: 2.0,color: const Color(0xFF282828),),borderRadius: BorderRadius.all(Radius.circular(2.0),),),height: 42.0,),),

第5步:还原效果

Flutter布局锦囊---涂鸦风格按钮相关推荐

  1. Flutter布局锦囊---绑定手机页

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "顶部导航栏",标题+取消按钮+跳过按钮的应用栏. "手机号输入框",用于获取手机号码的圆角边框输入字 ...

  2. Flutter布局锦囊---完善信息页

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "用户昵称输入",获取用户输入的昵称信息. "用户头像选取",获取用户选取作为头像的图片. " ...

  3. Flutter布局锦囊---蜡笔画的表单

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "手机号输入框",使用自定义的登录表单字段组件实现的输入框. "验证码输入框",使用自定义的登录表单验 ...

  4. Flutter布局锦囊---手机号登录页

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "运营位",使用自定义的旋转木马滑块组件实现可以滚动的运营位. "登录表单",使用自定义的登录表单组件 ...

  5. Flutter布局锦囊---带输入字段的应用栏

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "堆栈容器",使用大小框(SizedBox)和堆栈(Stack)组件搞的容器,用于实现层次结构. "下层的导航& ...

  6. Flutter布局锦囊---带彩条的文本字段

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "文本输入框",使用文本字段(TextField)组件实现的输入框. "状态指示条",使用容器(Con ...

  7. Flutter布局锦囊---验证码倒计时

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "获取验证码按钮",可以通过点击按钮来获取验证码. 然后就可以开始进行编码了. 第1步:绘制组件树 第2步:实现" ...

  8. Flutter布局锦囊---轮播图片与滑块

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "运营位",可以通过左右滑动来切换图片. "进度条",显示"运营位"当前位置的进度 ...

  9. Flutter布局锦囊---圆框的表单字段

    设计给的效果如下: 拿到设计后,先把整体拆分成几个部分: "黑色圆角边框",因为文本字段(TextField)组件的没有符合需求的样式,所以要自己做一个边框. "文本输入 ...

最新文章

  1. fabric 启动peer_编写 Fabric 链码的一般准则
  2. Matlab中设置图形窗口的大小、字体、axis等
  3. emq认证mysql后如何使用_EMQ 认证设置和acl访问控制
  4. IDEA打开html文件时显示错误browser error提示找不到chrome或者别的浏览器
  5. 当前安卓App加固到底该如何做到防篡改?
  6. mysql 复制 二进制文件命令_Mysql中复制详细解析
  7. 面试官系统精讲Java源码及大厂真题 - 38 线程池源码面试题
  8. SecureCRT打开文件中文乱码
  9. mongo数据排序和分页显示
  10. 【转】SQL SERVER 获取存储过程返回值
  11. java day58【 案例:使用 spring 的 IoC 的实现账户的 CRUD 、 基于注解的 IOC 配置 、 Spring 整合 Junit[掌握] 】...
  12. CleanShot X for mac(支持标注的截图录屏工具)
  13. 迷你世界显示服务器错误,迷你世界登陆失败怎么办-迷你世界登陆未成功_牛游戏页游...
  14. win10开启无线网卡服务器,win10系统设置开启或者禁用无线网卡的恢复步骤
  15. CORS手机测试软件,司南导航RTK手簿软件测量大师连接千寻cors账号进行测量的方法教程...
  16. 无法安装冰点还原_教程|有备有还,再备不难,如何实现整机还原?
  17. win7取消计算机密码怎么设置,Windows7取消开机密码怎么设置_Win7怎么取消开机密码?-192路由网...
  18. C语言编程>第二十七周 ③ 请补充fun函数,该函数的功能是计算并输出下列多项式的值:
  19. 热血篮球维修服务器是怎么回事,新浪《热血篮球》10月30日停服维护及更新公告...
  20. 无线路由器wan口和lan口

热门文章

  1. java 递增 实现_Java编程实现递增排序链表的合并
  2. 【caffe】ubuntu配置python接口----pycaffe
  3. 剑指 Offer 55 - I. 二叉树的深度
  4. ROS的优势与不足(除了ROS 机器人自主定位导航还能怎么做?)
  5. LeetCode 面试题 08.01. 三步问题 (动态规划)
  6. 【Angular 4】Can't bind to 'ngModel' since it isn't a known property of 'input'
  7. 敏捷开发般若敏捷系列之三:什么是敏捷(下)(无住,不住于空,破空执,非法,非非法)...
  8. 使用selenium 驱动最新火狐浏览器出错:ConnectionAbortedError: [WinError 10053] 你的主机中的软件中止了一个已建立的连接。...
  9. HDU 1422 重温世界杯 (dp)
  10. 设计模式(一)—单例模式