Flutter如何添加约束布局组件-Flutter_ConstraintLayout(登陆页面为例)

注我,一起成长,一起变强。

1.约束布局的核心

任何UI布局核心在于计算子控件的大小和位置。而约束布局的核心在于使用约束布局来计算子控件的大小和位置,

2.约束布局优势

  • • 2.1. 可以减少UI而已层级,使布局层次更加扁平化,可以提升渲染性能。

  • • 2.2. 所见即所得的灵活排版布局能力,可以更高效的开发UI页面。

Android 中有约束布局组件,而flutter也有开源的第三方组件:https://github.com/hackware1993/Flutter_ConstraintLayout

支持Android/iOS/linux/MacOS/Web/Windows

3.pubspec.yaml添加依赖

    flutter_constraintlayout: ^1.7.0-stable

4.使用示例

4.1 使用示例

import 'package:flutter/material.dart';
import 'package:flutter_constraintlayout/flutter_constraintlayout.dart';

class ConstraintLayoutPage extends StatefulWidget {
  const ConstraintLayoutPage({Key? key}) : super(key: key);

  @override
  State<ConstraintLayoutPage> createState() => _ConstraintLayoutPageState();
}

class _ConstraintLayoutPageState extends State<ConstraintLayoutPage> {
  final ConstraintId appLogoId = ConstraintId('appLogoId');
  final ConstraintId appTitleId = ConstraintId('appTitleId');
  final ConstraintId appAccountId = ConstraintId('appAccountId');
  final ConstraintId passwordId = ConstraintId('passwordId');
  final ConstraintId loginId = ConstraintId('loginId');
  final ConstraintId registId = ConstraintId('registId');
  final ConstraintId otherId = ConstraintId('otherId');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('ConstraintLayout'),
      ),
      body: ConstraintLayout(
        children: <Widget>[
          _buildAppLogo(),
          _buildAppTitle(),
          _buildInputContainer(
            id: appAccountId,
            topConstraint: appTitleId.bottom.margin(40),
            hintText: '请输入账户名',
            icon: Icons.person,
          ),
          _buildInputContainer(
            id: passwordId,
            topConstraint: appAccountId.bottom.margin(20),
            hintText: '请输入密码',
            icon: Icons.password,
          ),
          _buildElevatedButton(
            id: loginId,
            topConstraint: passwordId.bottom.margin(70),
            buttonText: '登陆',
            backgroundColor: const Color(0xff5B70CF),
          ),
          _buildElevatedButton(
            id: registId,
            topConstraint: loginId.bottom.margin(30),
            buttonText: '注册',
            backgroundColor: const Color(0xffF8644E),
          ),
          _buildTextWithConstraints(
            id: otherId,
            text: '其他方式登录',
            topConstraint: registId.bottom.margin(60),
            centerHorizontalTo: parent,
          ),
          _buildSocialLoginRow(),
        ],
      ),
    );
    // // AppBar
  }
  // 构建logo
  Widget _buildAppLogo() {
    return Image.asset(
      'assets/images/login/app_logo.png',
      width: 120,
    ).applyConstraint(
      top: parent.top.margin(60),
      left: parent.left.margin(20),
      right: parent.right.margin(20),
      id: appLogoId,
    );
  }
  // 构建app的名称
  Widget _buildAppTitle() {
    return const Text(
      "APP Name",
      style: TextStyle(fontSize: 20, color: Color(0xFFBECEFA)),
    ).applyConstraint(
      id: appTitleId,
      top: appLogoId.bottom.margin(10),
      left: parent.left,
      right: parent.right,
    );
  }

  // 构建输入框:账号/密码
  Widget _buildInputContainer({
    required ConstraintId id,
    required ConstraintAlign topConstraint,
    required String hintText,
    required IconData icon,
  }) {
    return Container(
      color: const Color(0xFFF0F5FD),
      child: Row(
        children: [
          const SizedBox(width: 10),
          Icon(icon),
          const SizedBox(width: 20),
          Expanded(
            child: TextField(
              style: const TextStyle(
                color: Color(0xffA0ACD4),
                fontSize: 20,
              ),
              decoration: InputDecoration(
                border: InputBorder.none,
                hintText: hintText,
                hintStyle: const TextStyle(color: Color(0xffA0ACD4)),
                labelStyle: const TextStyle(color: Color(0xffA0ACD4)),
              ),
            ),
          ),
        ],
      ),
    ).applyConstraint(
      id: id,
      width: matchConstraint,
      height: 60,
      top: topConstraint,
      left: parent.left.margin(20),
      right: parent.right.margin(20),
    );
  }

  // 构建登陆/注册
  Widget _buildElevatedButton({
    required ConstraintId id,
    required ConstraintAlign topConstraint,
    required String buttonText,
    required Color backgroundColor,
  }) {
    return ElevatedButton(
      onPressed: () {
        debugPrint('点击了按钮:$buttonText');
      },
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(backgroundColor),
      ),
      child: Text(
        buttonText,
        style: const TextStyle(
          fontSize: 20,
          color: Colors.white,
        ),
      ),
    ).applyConstraint(
      id: id,
      top: topConstraint,
      width: matchConstraint,
      height: 60,
      left: parent.left.margin(120),
      right: parent.right.margin(120),
    );
  }

  // 构造说明文本
  Widget _buildTextWithConstraints({
    required ConstraintId id,
    required String text,
    required ConstraintAlign topConstraint,
    required ConstraintId centerHorizontalTo,
  }) {
    return Text(
      text,
      style: const TextStyle(
        fontSize: 16,
        color: Color(0xFFD5DFF2),
      ),
    ).applyConstraint(
      id: id,
      left: parent.left,
      right: parent.right,
      top: topConstraint,
      centerHorizontalTo: centerHorizontalTo,
    );
  }
  // 构建其它登录方式:微信,QQ,微博
  Widget _buildSocialLoginRow() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        GestureDetector(
          onTap: () {
            debugPrint('点击了微信登录');
          },
          child: Image.asset(
            'assets/images/login/wechat.png',
            width: 40,
            height: 40,
          ),
        ),
        const SizedBox(width: 20),
        InkWell(
          onTap: () {
            debugPrint('点击了QQ登录');
          },
          child: Image.asset(
            'assets/images/login/qq.png',
            width: 40,
            height: 40,
          ),
        ),
        const SizedBox(width: 20),
        InkWell(
          onTap: () {
            debugPrint('点击了微博登录');
          },
          child: Image.asset(
            'assets/images/login/weibo.png',
            width: 40,
            height: 40,
          ),
        ),
      ],
    ).applyConstraint(
      width: matchParent,
      top: otherId.bottom.margin(20),
    );
  }
}

5.效果

Flutter如何添加约束布局组件-Flutter_ConstraintLayout(登陆页面为例)

6.其它

6.1. 和前文Flutter如何添加布局-Flutter系统布局(登陆页面为例)使用系统布局相比

  • • 使用上,UI层级有所减少;

  • • 性能上,性能提升多少和页面嵌套,复杂程度有关;对于一般简单页面,性能差异很很小。

  • • 学习成本上,有一定的提升;对熟悉Android约束布局的同学,无缝切换;

  • • 开发体验上,用法不当时,抛出一堆异常错误,没有系统原生布局直观,开发体验并不好。

选择使用哪种页面布局方式,可以根据项目,团队的情况,做出适当的选择;适合自己的就好。


原文始发于微信公众号(客户端全栈技术养成记):Flutter如何添加约束布局组件-Flutter_ConstraintLayout(登陆页面为例)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/289076.html

(0)
土豆大侠的头像土豆大侠

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!