最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    正文概述 掘金(ZeroFlutter)   2021-04-23   600

    粗略一看
    嗯?... 很漂亮... 很笔优特佛(Beautiful)?
    再粗略一看
    ?小老弟,你唬我呢?不就是个登录注册页面吗?
    再仔细一看
    不对?,居然有下面?这么多的知识点

    核心知识点

    • Container
    • Text
    • Image
    • Column
    • Row
    • Stack
    • SizedBox
    • TextField
    • Padding
    • Spacer
    • Positioned
    • GestureDetector
    • Divider
    • ClipPath
    • Path
    • Bezier(贝塞尔曲线)
    • Flutter 组件抽离

    看完文章,点赞后再点击对应的 Widget 可直接进入 Flutter 官方文档?,(超级贴心?)

    • 先赞后看,更新永不断?
    • 好的,我们进入正题

    ? 项目介绍 ?

    这是我的第 2 个 Speed Code 视频项目文章,通过此文章你可以学习到如上 Widget基础进阶用法,更重要的你可以学习到如何将这些 Widget 灵活的组合,最终实现上面?的效果。

    定义通用主题

    • 大小
    /// theme/app_size.dart
    import 'package:flutter/material.dart';
    
    // 标题文字大小
    const double kTitleTextSize = 24;
    // 内容体文字大小
    const double kBodyTextSize = 14;
    // 按钮文字大小
    const double kBtnTextSize = 18;
    // 按钮圆角半径
    const double kBtnRadius = 24;
    // 输入框边框圆角半径
    const double kInputBorderRadius = 5;
    // icon 大小
    const double kIconSize = 24;
    // icon 盒子大小
    const double kIconBoxSize = 56;
    // Light 字重
    const FontWeight kLightFontWeight = FontWeight.w300;
    // Medium 字重
    const FontWeight kMediumFontWeight = FontWeight.w500;
    
    
    • 颜色
    /// theme/app_colors.dart
    import 'package:flutter/widgets.dart';
    
    // 背景颜色
    const Color kBgColor = Color(0xFFFEDCE0);
    // 文字颜色
    const Color kTextColor = Color(0xFF3D0007);
    // 按钮开始颜色
    const Color kBtnColorStart = Color(0xFFF89500);
    // 按钮结束颜色
    const Color kBtnColorEnd = Color(0xFFFA6B74);
    // 按钮投影颜色
    const Color kBtnShadowColor = Color(0x33D83131);
    // 输入框边框颜色
    const Color kInputBorderColor = Color(0xFFECECEC);
    
    // 按钮渐变背景色
    const LinearGradient kBtnLinearGradient = LinearGradient(
      colors: [
        kBtnColorStart,
        kBtnColorEnd,
      ],
    );
    
    
    • 样式
    /// theme/app_style.dart
    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    import 'app_colors.dart';
    import 'app_size.dart';
    
    // 按钮投影
    const List<BoxShadow> kBtnShadow = [
      BoxShadow(
        color: kBtnShadowColor,
        offset: Offset(0, 8),
        blurRadius: 20,
      )
    ];
    
    // 按钮文字样式
    const TextStyle kBtnTextStyle = TextStyle(
      color: kBtnColorStart,
      fontSize: kBtnTextSize,
      fontWeight: kMediumFontWeight,
    );
    
    // 标题文字样式
    const TextStyle kTitleTextStyle = TextStyle(
      fontSize: kTitleTextSize,
      color: kTextColor,
      fontWeight: kMediumFontWeight,
    );
    
    // 内容文字样式
    const TextStyle kBodyTextStyle = TextStyle(
      fontSize: kBodyTextSize,
      color: kTextColor,
      fontWeight: kLightFontWeight,
    );
    
    // 输入框边框
    OutlineInputBorder kInputBorder = OutlineInputBorder(
      borderRadius: BorderRadius.circular(5),
      borderSide: BorderSide(
        color: kInputBorderColor,
        width: 1,
      ),
    );
    
    

    构建欢迎页面

    绘制头部内容

    • 1、绘制头部背景
    // WelBgHeader
    Image.asset(
      'assets/images/bg_welcome_header.png'
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 2、绘制 App Icon
    // AppIconWidget
    Container(
      width: kIconBoxSize,
      height: kIconBoxSize,
      decoration: BoxDecoration(
        color: Colors.white,
        shape: BoxShape.circle,
      ),
      alignment: Alignment.center,
      child: Image.asset(
        'assets/icons/app_icon.png',
        width: 24,
        height: 32,
      ),
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 3、绘制 Icon 下的文字
    /// Icon Text
    Positioned(
      top: 194,
      left: 40,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          AppIconWidget(),
          SizedBox(height: 8),
          Text(
            'Sour',
            style: kTitleTextStyle,
          ),
          SizedBox(height: 8),
          Text(
            'Best drink\nreceipes',
            style: kBodyTextStyle,
          ),
        ],
      ),
    ),
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 4、设置整体背景色
    /// WelcomePage
    Scaffold(
      backgroundColor: kBgColor,
      body: Column(
        children: [
          WelcomeHeaderWidget(),
        ],
      ),
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    绘制底部内容

    • 1、绘制按钮渐变色背景
    // 按钮渐变背景色
    const LinearGradient kBtnLinearGradient = LinearGradient(
      colors: [
        kBtnColorStart,
        kBtnColorEnd,
      ],
    );
    // 按钮投影
    const List<BoxShadow> kBtnShadow = [
      BoxShadow(
        color: kBtnShadowColor,
        offset: Offset(0, 8),
        blurRadius: 20,
      )
    ];
    // 渐变色按钮
    // GradientBtnWidget
    SizedBox(
      width: width,
      height: 48,
      child: GestureDetector(
        onTap: onTap,
        child: Container(
          decoration: BoxDecoration(
            // 设置渐变色
            gradient: kBtnLinearGradient,
            // 设置投影
            boxShadow: kBtnShadow,
    		    // 设置圆角半径
            borderRadius: BorderRadius.circular(kBtnRadius),
          ),
          alignment: Alignment.center,
          child: child,
        ),
      ),
    )
    
    • 2、绘制文字
    // 按钮文字样式
    const TextStyle kBtnTextStyle = TextStyle(
      color: kBtnColorStart,
      fontSize: kBtnTextSize,
      fontWeight: kMediumFontWeight,
    );
    // 白色按钮文字
    // BtnTextWhiteWidget
    Text(
      text,
      style: kBtnTextStyle.copyWith(
        color: Colors.white,
      ),
    )
    
    • 3、组合
    // Sign up 按钮
    GradientBtnWidget(
      width: 208,
      child: BtnTextWhiteWidget(text: 'Sign up'),
      onTap: () {},
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 4、绘制登录按钮
    // LoginBtnWidget
    Container(
      height: 48,
      width: 208,
      decoration: BoxDecoration(
        // 设置白色
        color: Colors.white,
        // 设置圆角半径
        borderRadius: BorderRadius.circular(kBtnRadius),
        // 设置投影
        boxShadow: kBtnShadow,
      ),
      alignment: Alignment.center,
      child: Text(
        'Login',
        style: kBtnTextStyle,
      ),
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 5、添加忘记密码文字
    // 忘记密码
    Text(
      'Forgot password?',
      style: TextStyle(
        fontSize: 18,
        color: kTextColor,
      ),
    )
    
    • 6、绘制底部社交媒体第三方登录
    
    // 登录方式图标
    class LoginTypeIconWidget extends StatelessWidget {
      const LoginTypeIconWidget({
        Key key,
        this.icon,
      }) : super(key: key);
      final String icon;
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 10),
          child: Image.asset(
            icon,
            width: 16,
            height: 16,
          ),
        );
      }
    }
    
    // 横线
    class LineWidget extends StatelessWidget {
      const LineWidget({
        Key key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          child: Divider(color: kTextColor),
          width: 80,
        );
      }
    }
    /// 组合起来
    Row(
      children: [
        Spacer(),
        LineWidget(),
        LoginTypeIconWidget(icon: 'assets/icons/logo_ins.png'),
        LoginTypeIconWidget(icon: 'assets/icons/logo_fb.png'),
        LoginTypeIconWidget(icon: 'assets/icons/logo_twitter.png'),
        LineWidget(),
        Spacer(),
      ],
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    登录页面

    绘制头部区域

    • 1、绘制背景
    Scaffold(
      // 设置背景为白色
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Image.asset(
            'assets/images/bg_login_header.png'
          ),
        ],
      ),
    );
    
    • 2、绘制返回按钮
    // BackIcon
    GestureDetector(
      onTap: () {
        // 返回
        Navigator.pop(context);
      },
      child: Container(
        width: 56,
        height: 56,
        decoration: BoxDecoration(
          // 白色背景
          color: Colors.white,
          // 设置圆形
          shape: BoxShape.circle,
        ),
        // 【这里很重要】设置居中
        alignment: Alignment.center,
        child: Image.asset(
          'assets/icons/icon_back.png',
          width: 24,
          height: 24,
        ),
      ),
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    绘制输入区域内容

    • 1、绘制文字
    // 登录文字内容,可以看上面全局定义的样式
    Text(
      'Login',
      style: kTitleTextStyle,
    ),
    SizedBox(height: 20),
    Text(
      'Your Email',
      style: kBodyTextStyle,
    ),
    
    • 2、绘制输入框
    // LoginInput
    TextField(
      decoration: InputDecoration(
        // 缺省文字
        hintText: hintText,
        // 边框
        border: kInputBorder,
        focusedBorder: kInputBorder,
        enabledBorder: kInputBorder,
        // 输入框前面的邮件图标
        prefixIcon: Container(
          width: kIconBoxSize,
          height: kIconBoxSize,
          // 【这里很重要,再次强调】不然会拉升
          alignment: Alignment.center,
          child: Image.asset(
            prefixIcon,
            width: kIconSize,
            height: kIconSize,
          ),
        ),
        // 设置是否为密码样式
        obscureText: obscureText,
        // 设置文字样式
        style: kBodyTextStyle.copyWith(
          fontSize: 18,
        ),
    )
    
    • 3、组合样式
    // LoginBodyWidget - Column
    SizedBox(height: 4),
    LoginInput(
      hintText: 'Email',
      prefixIcon: 'assets/icons/icon_email.png',
    ),
    SizedBox(height: 16),
    Text(
      'Your Password',
      style: kBodyTextStyle,
    ),
    SizedBox(height: 4),
    LoginInput(
      hintText: 'Password',
      prefixIcon: 'assets/icons/icon_pwd.png',
    ),
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • 4、绘制登录按钮
    // 登录按钮
    Row(
      children: [
        Spacer(),
        // 渐变背景组件
        GradientBtnWidget(
          child: Row(
            children: [
              SizedBox(width: 34),
              // 白色文字
              BtnTextWhiteWidget(text: 'Login'),
              Spacer(),
              // 向右图标
              Image.asset(
                'assets/icons/icon_arrow_right.png',
                width: kIconSize,
                height: kIconSize,
              ),
              SizedBox(width: 24),
            ],
          ),
          width: 160,
          onTap: () {
            // 点击登录,这里模拟返回了
            Navigator.pop(context);
          },
        ),
      ],
    )
    

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期**

    绘制曲线剪裁

    可以先看看这个曲线设计的整体路径,找出6个控制点4个坐标点
    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    • p:坐标点
    • c:控制点
    // 我们是用路径剪裁
    ClipPath(
      clipper: LoginCliper(),
      child: LoginBodyWidget(),
    ),
    
    // 登录页面剪裁曲线
    class LoginCliper extends CustomClipper<Path> {
      // 第一个点
      Point p1 = Point(0.0, 54.0);
      Point c1 = Point(20.0, 25.0);
      Point c2 = Point(81.0, -8.0);
      // 第二个点
      Point p2 = Point(160.0, 20.0);
      Point c3 = Point(216.0, 38.0);
      Point c4 = Point(280.0, 73.0);
      // 第三个点
      Point p3 = Point(280.0, 44.0);
      Point c5 = Point(280.0, -11.0);
      Point c6 = Point(330.0, 8.0);
    
      @override
      Path getClip(Size size) {
        // 第四个点
        Point p4 = Point(size.width, .0);
    
        Path path = Path();
        // 移动到起始点
        path.moveTo(p1.x, p1.y);
        // 第 1 段三阶贝塞尔曲线
        path.cubicTo(c1.x, c1.y, c2.x, c2.y, p2.x, p2.y);
        // 第 2 段三阶贝塞尔曲线
        path.cubicTo(c3.x, c3.y, c4.x, c4.y, p3.x, p3.y);
        // 第 3 段三阶贝塞尔曲线
        path.cubicTo(c5.x, c5.y, c6.x, c6.y, p4.x, p4.y);
        // 右下角
        path.lineTo(size.width, size.height);
        // 左下角
        path.lineTo(0, size.height);
        // 闭合
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
        return oldClipper.hashCode != this.hashCode;
      }
    }
    

    最终效果

    Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    源码

    • GitHub-flutter_drink_login_app(居然提供源码,我反手就是一个 Star)

    视频

    • BiliBili-(视频内容首发站点)

    关于我

    • 15 年~18 年,使用 Android 原生做智能硬件相关的  App 研发
    • 18 年 5 月,一次偶然的机会接触到了 Flutter ,然后开始自学,可以看 weather_flutter 是我练习 Flutter 的入门实战项目(我现在依然觉得他非常适合 Flutter 入门练习使用)
    • 18 年 8 月,顶着巨大的压力(Flutter 当时还没有 Release 1.0)开始使用 Flutter 开发企业级项目,并且开发维护了十几个 Flutter 插件包(因为当时插件资源非常的匮乏)
    • 截止目前主导并参与上线了 4 款企业级 Flutter App,当前正在负责的一款 App 累计用户 120W+,使用 Flutter 得到了极佳的体验

    致谢

    • 感谢 Elizabeth Arostegui 提供的非常漂亮的设计图,这是她的 Figma 主页
    • 如果你也有很棒的设计图,那么可以联系我制作出 App 分享给大家

    ? 掘金官方活动 ?

    • 推荐本文到沸点,掘金徽章、100元京东卡、掘金搪瓷杯、五折小册码,好礼拿不停
    • 查看活动详情

    本文推荐语示例

    • 示例 1
    【好文一起看】为这篇文章点赞???,有很多 Flutter Widget 的基础和进阶用法,把这些 Widget 灵活巧妙的组合在一起,完成了超级漂亮的欢迎、登录页面,快和我一起来围观吧 #好文推荐#
    
    • 示例 2
    【好文一起看】在 Flutter 上贝塞尔曲线居然可以这么简单了?,文章超详细的注释和配图,让我很轻松就理解了优美的贝塞尔曲线剪裁,最重要还附带视频和源码,强烈推荐 ??? #好文推荐#
    

    起源地下载网 » Flutter 手把手写出超漂亮的登录注册 UI - 饮料食谱App - Speed Code | 创作者训练营第二期

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元