flutter 创建一个支持所有widget的按钮(按下变色)

1,035 阅读1分钟

Flutter 自带的按钮一般都是通过 ThemeData 改变颜色的,缺点是只支持特定的 Widget。例如 IconButton,只支持 Icon 这个 Widget 改变颜色。

有什么方法可以支持所有 Widget 呢?我想到的是定义一个回调函数返回需要改变颜色的 Widget,然后把 Color 作为参数传进去。

下面是代码:

import 'package:flutter/material.dart';

typedef NButtonBuilder = Widget Function(Color color);

class NButton extends StatefulWidget {
  final Function onPressed;
  final Color color;
  final Color hoverColor;
  final NButtonBuilder builder;

  NButton(
      {@required this.builder,
      this.onPressed,
      this.color,
      this.hoverColor,
      Key key})
      : super(key: key);

  @override
  _NButtonState createState() => _NButtonState();
}

class _NButtonState extends State<NButton> {
  bool isOn = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: widget.builder(isOn ? widget.hoverColor : widget.color),
      onTapDown: (TapDownDetails details) {
        setState(() {
          isOn = true;
        });
      },
      onTapUp: (TapUpDetails details) {
        setState(() {
          isOn = false;
        });
      },
      onTapCancel: () {
        setState(() {
          isOn = false;
        });
      },
      onTap: widget.onPressed,
      behavior: HitTestBehavior.opaque,
    );
  }
}

使用方法:

NButton(
      builder: (Color color) =>
          SvgPicture.asset(
            'assets/svg/ic_search_clear_grey_24dp.svg',
            width: 40,
            height: 40,
            color: color,
          ),
      color: Color.fromRGBO(120, 120, 120, 1),
      hoverColor: Color.fromRGBO(120, 120, 120, 0.5),
      onPressed: () {},
    )