卡片设置

一个用于构建基于卡片的设置表单的 Flutter 包。它包含一个预构建表单字段小部件库。风格有点像 Cupertino 设置屏幕和 Material Design 的混合体;其理念是它应该在 iOS 和 Android 上都可用且直观。

Card-Settings

此包由 CardSettings 布局包装器和一系列表单字段选项组成,包括:

  • 文本框
    • CardSettingsText - 基本文本框
    • CardSettingsParagraph - 带计数器的多行文本框
    • CardSettingsEmail - 一个为电子邮件输入预配置的文本框
    • CardSettingsPassword - 一个为密码预配置的文本框
    • CardSettingsPhone - 一个带掩码的电话输入框(目前是美国风格)
  • 数字字段
    • CardSettingsDouble - 用于双精度数字的字段
    • CardSettingsInt - 用于整数的字段
    • CardSettingsCurrency - 用于货币输入的字段
    • CardSettingsSwitch - 用于布尔状态的字段
  • 选择器
    • CardSettingsListPicker - 任意选项的选择列表
    • CardSettingsNumberPicker - 指定范围内的数字选择列表
    • CardSettingsColorPicker - RGB 颜色选择器
    • CardSettingsDatePicker - Material Design 日期选择器
    • CardSettingsTimePicker - Material Design 时间选择器
  • 选择
    • CardSettingsMultiselect - 从可用选项列表中选择
  • 信息部分
    • CardSettingsHeader - 用于在表单部分之间添加标题的控件
    • CardSettingsInstructions - 信息性只读文本
  • 操作
    • CardSettingsButton - 表单的操作按钮

所有字段都支持 validateonChangeonSavedautovalidatevisible

该包还包括以下附加项目:

  • CardSettingsField - 基础布局小部件。您可以使用它来构建自定义字段
  • Converters - 一组实用函数,用于协助数据在字段之间进行转换

简单示例

此包中的所有字段都兼容标准的 Flutter Form 小部件。只需将 CardSettings 控件包装在表单中,并像平常一样使用其表单功能即可。

  String title = "Spheria";
  String author = "Cody Leet";
  String url = "http://www.codyleet.com/spheria"

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
      body: Form(
        key: _formKey,
        child: CardSettings(
          children: <Widget>[
            CardSettingsHeader(label: 'Favorite Book'),
            CardSettingsText(
              label: 'Title',
              initialValue: title,
              validator: (value) {
                if (value == null || value.isEmpty) return 'Title is required.';
              },
              onSaved: (value) => title = value,
            ),
            CardSettingsText(
              label: 'URL',
              initialValue: url,
              validator: (value) {
                if (!value.startsWith('http:')) return 'Must be a valid website.';
              },
              onSaved: (value) => url = value,
            ),
          ],
        ),
      ),
    );
  }

在此处查看完整的演示示例:此处

主题化

这些小部件支持 Material Design 主题。此示例显示了要设置哪些全局主题值来确定各种元素的显示方式。

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Card Settings Example',
      home: new HomePage(),
      theme: ThemeData(
        accentColor: Colors.indigo[400], // used for card headers
        cardColor: Colors.white, // used for field backgrounds
        backgroundColor: Colors.indigo[100], // color outside the card
        primaryColor: Colors.teal, // color of page header
        buttonColor: Colors.lightBlueAccent[100], // background color of buttons
        textTheme: TextTheme(
          button: TextStyle(color: Colors.deepPurple[900]), // style of button text
          subhead: TextStyle(color: Colors.deepOrange[900]), // style of input text
        ),
      ),
    );
  }
}

或者,如果您想为 CardSettings 层级结构应用不同的主题,您可以像这样将其包装在 Theme 小部件中:

  Theme(
    data: Theme.of(context).copyWith(
      primaryTextTheme: TextTheme(
        title: TextStyle(color: Colors.lightBlue[50]), // style for headers
      ),
      inputDecorationTheme: InputDecorationTheme(
        labelStyle: TextStyle(color: Colors.deepPurple), // style for labels
      ),
    ),
    child: CardSettings(
      ...
    ),
  )

全局属性

CardSettings 小部件实现了几个全局设置,所有子字段都可以继承。目前它仅支持标签自定义。

标签

您可以通过四个属性来控制标签的渲染方式:

  CardSettings(
    labelAlign: TextAlign.right, // change the label alignment
    labelSuffix: ':', // add an optional tag after the label
    labelPadding: 10.0, // control the spacing between the label and the content
    contentAlign: TextAlign.left, // alignment of the entry widgets
    icon: Icon(Icons.person), // puts and option icon to the left of the label
    requiredIndicator: Text('*', style: TextStyle(color: Colors.red)), // puts an optional indicator to the right of the label
  )

labelAligncontentAlign 属性也可在每个字段上使用,因此您可以为单个字段覆盖全局设置。

  CardSettingsText(
    label: 'Last Name',
    labelAlign: TextAlign.left,
    contentAlign: TextAlign.right,
  )

动态可见性

每个字段都实现了一个 visible 属性,您可以使用它来根据其他字段的值控制可见性。在此示例中,开关字段控制文本框的可见性。

  bool _ateOut = false;

  CardSettingsSwitch(
    label: 'Ate out?',
    initialValue: _ateOut,
    onChanged: (value) => setState(() => _ateOut = value),
  ),

  CardSettingsText(
    label: 'Restaurant',
    visible: _ateOut,
  ),

掩码

CardSettingsText 小部件具有 inputMask 属性,可强制输入的文本符合给定模式。这是基于 flutter_masked_text
包构建的,因此掩码使用以下字符格式化:

  • 0:接受数字
  • A:接受字母
  • @:接受数字和字母
  • *:接受任何字符

例如,电话号码将是“(000)000-0000”。

注意:CardSettingsPhone 是一个便利小部件,已预先配置为使用此模式。

注意:flutter_masked_text 是一个控制器,因此您不能同时使用 inputMask 和自定义控制器。这可能在将来得到解决。

方向

此套件允许进行方向切换。要进行配置,请根据 MediaQuery 提供的方向构建不同的布局。

您可能希望在每个布局中使用不同的字段,或者不同的字段顺序。为了避免 Flutter 在此情况下跟踪状态时感到困惑,您必须为每个单独的字段提供一个唯一的 state key,并在每个布局中使用相同的 key。

@override
Widget build(BuildContext context) {

  final GlobalKey<FormState> _emailKey = GlobalKey<FormState>();
  var orientation = MediaQuery.of(context).orientation;

  return Form
    key: _formKey,(
    child: (orientation == Orientation.portraitUp)
        ? CardSettings(children: <Widget>[
              // Portrait layout here
              CardSettingsEmail(key: _emailKey)
            ])
        : CardSettings(children: <Widget>[
              // Landscape layout here
              CardSettingsEmail(key: _emailKey)
            ]);
    },
  );
}

在横向模式下,您可以在同一行上放置多个字段。这通常需要使用容器小部件在行内提供布局。相反,您可以使用 CardFieldLayout 辅助小部件来简化此操作。它默认会使子项均匀分布,但您可以提供一个 flex 值数组来控制相对大小。

// equally spaced example
CardSettings(
  children: <Widget>[
    CardFieldLayout(children: <Widget>[
      CardSettingsEmail(),
      CardSettingsPassword(),
    ]),
  ],
);
// relative width example
CardSettings(
  children: <Widget>[
    CardFieldLayout_FractionallySpaced(
      children: <Widget>[
        CardSettingsEmail(),
        CardSettingsPassword(),
      ],
      flexValues: [2, 1], // 66% and 33% widths
    ),
  ],
);

自定义字段

CardSettingsField 是所有其他字段的基础,可用于构建此库之外的唯一字段。它的目的是以一致的装饰来管理布局。制作自定义字段的最佳方法是继承自 FormField<T>,它将管理您的字段状态。CardSettingsSwitch 小部件是这方面最清晰的例子。您只需要在 content 属性中提供自定义小部件。

GitHub

https://github.com/codegrue/card_settings