当前位置:   article > 正文

flutter:自定义组件_flutter 自定义组件

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,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
GradientButton(
   onPressed: () {
     print("点击了");
   },
   width: 200,
   height: 40,
   borderRadius: BorderRadius.circular(5),
   child: const Text("渐变按钮"),
 ),
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
遇到的问题:
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];

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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

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

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

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

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

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

在这里插入图片描述

创建一个带有控制器的组件

import 'package:flutter/material.dart';

// 创建一个继承自ValueNotifier的自定义控制器类
class MyController extends ValueNotifier<String> {
  MyController(String value) : super(value);

  // 创建一个方法用于修改widget属性值
  void updateValue(String newValue) {
    value = newValue;
    notifyListeners();
  }
}

// 创建一个带有控制器的widget
class MyWidget extends StatefulWidget {
  final MyController controller;

  MyWidget({required this.controller});

  
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  
  Widget build(BuildContext context) {
    return Text(
      widget.controller.value,
      // 其他属性设置
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/307825
推荐阅读
相关标签
  

闽ICP备14008679号