flutter:自定义组件

前言

参考:Flutter 实战

由于是初学者,因此只会学习一些基础的东西,对于复杂部分可以自行查看该书。

组合现有组件

这一部分还是比较好理解的,比如基于element提供的组件可以封装一个通用的业务组件,减少代码的耦合同时方便业务的开发。在flutter中也是如此,利用一些基本组件来组合成一个通用的业务组件。

有一点挺讨厌的,拿element来说,有一个组件列表,以及组件的使用文档。但是学习flutter这么久了,一直也不知道这些基本组件的使用文档在哪,只能通过看书、记笔记的方式来学习。

自定义渐变按钮

基本功能

  • 背景支持渐变色
  • 按下时有涟漪效果
  • 支持圆角

对文章中的代码进行了简单修改

import 'package:flutter/material.dart';

// 继承无状态组件
class GradientButton extends StatelessWidget {
    
    
  // 构造函数
  const GradientButton({
    
    
    Key? key,
    this.linearGradient, //渐变
    this.width, // 宽度
    this.height, // 高度
    this.borderRadius, //圆角
    required this.onPressed, //点击事件
    required this.child, // 子组件
  }) : super(key: key);

  // 渐变颜色组
  final LinearGradient? linearGradient;

  // 按钮宽高、圆角
  final double? width;
  final double? height;
  final BorderRadius? borderRadius;

  // 点击事件
  final GestureTapCallback onPressed;

  // 子组件
  final Widget child;

  
  Widget build(BuildContext context) {
    
    
    // 获取上下文主题
    ThemeData theme = Theme.of(context);

    // 处理渐变保证有一个默认值
    LinearGradient? newLinearGradient = linearGradient ??
        LinearGradient(colors: [theme.primaryColor, theme.primaryColorDark]);

    // DecoratedBox用于装饰其子组件的组件。它可以为子组件添加背景色、边框、圆角等装饰效果。
    return DecoratedBox(
      decoration: BoxDecoration(
          gradient: newLinearGradient, //线性渐变
          borderRadius: borderRadius),
      child: Material(
        type: MaterialType.transparency,
        // InkWell可以产生水波的效果
        child: InkWell(
          highlightColor: Colors.transparent,
          borderRadius: borderRadius,
          onTap: onPressed,
          // 宽高被限制的组件
          child: ConstrainedBox(
            // 如果height和width为null,会自适应子组件带
            constraints: BoxConstraints.tightFor(height: height, width: width),
            child: Center(
              child: Padding(
                padding: const EdgeInsets.all(8),
                child: DefaultTextStyle(
                  style: const TextStyle(fontWeight: FontWeight.bold),
                  child: child,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
GradientButton(
   onPressed: () {
    
    
     print("点击了");
   },
   width: 200,
   height: 40,
   borderRadius: BorderRadius.circular(5),
   child: const Text("渐变按钮"),
 ),

在这里插入图片描述
遇到的问题:
1、就是知识储备不够,好多组件根本就不知道
2、第二个就是flutter对于类型越来越严格,以文章中的代码为例

  const GradientButton({
    
    Key? key, 
    this.colors,
    this.width,
    this.height,
    this.onPressed,
    this.borderRadius,
    required this.child,
  }) : super(key: key);

  // 渐变色数组
  final List<Color>? colors;

//确保colors数组不空
    List<Color> _colors =
        colors ?? [theme.primaryColor, theme.primaryColorDark];

虽然颜色数组不为null了,但是如果是[],是会报错的,线性渐变组件最少要有两个颜色值。
最初我的改法是

 List<Color>_color = (colors==null || colors.isEmpty) ? [theme.primaryColor, theme.primaryColorDark] :colors;

但是编译器一直提示我改为

 List<Color>?_color = (colors==null || colors.isEmpty) ? [theme.primaryColor, theme.primaryColorDark] :colors;

因为前面设置了colors可以为空,final List<Color>? colors;colors不为空是_color 赋值后的类型就必须是 List<Color>?;但是LinearGradient要求参数的类型必须是List<Color>,所以就导致编译不通过。

这里不是说作者代码写的不好,是感慨flutter越来越完善,越来越严格了。以前可以正常运行的代码,现在在编译器里都会给予提示,就比如编译器会让你在组件前面加一个const

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41897680/article/details/131246181