是否有一个cupertino equivelent的SwitchListTile?

时间:2018-04-29 21:15:10

标签: flutter

我需要为我的iOS应用创建一个设置页面。在我的Android端,我有SwitchListTile很好地布局开关。

是否有一个Flutter小部件可以帮助我或者我必须自己写一个?

2 个答案:

答案 0 :(得分:2)

你必须自己编写一个,但是你可以很容易地从SwitchListTile源中编写一个:

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  bool _isSelected = false;

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new SafeArea(
          child: new Material(
              child: new ListView(
                children: <Widget>[
                  new CupertinoSwitchListTile(
                    value: _isSelected,
                    onChanged: (value) {
                      print("Value changed to $value");
                      setState(() => _isSelected = value);
                    },
                    activeColor: CupertinoColors.activeGreen
                  )
                ],
              ))),
    );
  }

}

class CupertinoSwitchListTile extends StatelessWidget {
  /// This has been shamelessly copied from Material/SwitchListTile.
  /// The applicable license applies.
  const CupertinoSwitchListTile({
    Key key,
    @required this.value,
    @required this.onChanged,
    this.activeColor,
    this.title,
    this.subtitle,
    this.isThreeLine: false,
    this.dense,
    this.secondary,
    this.selected: false,
  })  : assert(value != null),
        assert(isThreeLine != null),
        assert(!isThreeLine || subtitle != null),
        assert(selected != null),
        super(key: key);

  /// Whether this switch is checked.
  ///
  /// This property must not be null.
  final bool value;

  /// Called when the user toggles the switch on or off.
  ///
  /// The switch passes the new value to the callback but does not actually
  /// change state until the parent widget rebuilds the switch tile with the
  /// new value.
  ///
  /// If null, the switch will be displayed as disabled.
  ///
  /// The callback provided to [onChanged] should update the state of the parent
  /// [StatefulWidget] using the [State.setState] method, so that the parent
  /// gets rebuilt; for example:
  ///
  /// ```dart
  /// new SwitchListTile(
  ///   value: _lights,
  ///   onChanged: (bool newValue) {
  ///     setState(() {
  ///       _lights = newValue;
  ///     });
  ///   },
  ///   title: new Text('Lights'),
  /// )
  /// ```
  final ValueChanged<bool> onChanged;

  /// The color to use when this switch is on.
  ///
  /// Defaults to accent color of the current [Theme].
  final Color activeColor;

  /// The primary content of the list tile.
  ///
  /// Typically a [Text] widget.
  final Widget title;

  /// Additional content displayed below the title.
  ///
  /// Typically a [Text] widget.
  final Widget subtitle;

  /// A widget to display on the opposite side of the tile from the switch.
  ///
  /// Typically an [Icon] widget.
  final Widget secondary;

  /// Whether this list tile is intended to display three lines of text.
  ///
  /// If false, the list tile is treated as having one line if the subtitle is
  /// null and treated as having two lines if the subtitle is non-null.
  final bool isThreeLine;

  /// Whether this list tile is part of a vertically dense list.
  ///
  /// If this property is null then its value is based on [ListTileTheme.dense].
  final bool dense;

  /// Whether to render icons and text in the [activeColor].
  ///
  /// No effort is made to automatically coordinate the [selected] state and the
  /// [value] state. To have the list tile appear selected when the switch is
  /// on, pass the same value to both.
  ///
  /// Normally, this property is left to its default value, false.
  final bool selected;

  @override
  Widget build(BuildContext context) {
    var color =  activeColor ?? Theme.of(context).accentColor;
    print("Active color: ${color.red} ${color.green} ${color.blue}");
    final Widget control = new CupertinoSwitch(
      value: value,
      onChanged: onChanged,
      activeColor: activeColor ?? CupertinoColors.activeGreen,
    );
    return new MergeSemantics(
      child: ListTileTheme.merge(
        selectedColor: activeColor ?? CupertinoColors.activeGreen,
        child: new ListTile(
          leading: secondary,
          title: title,
          subtitle: subtitle,
          trailing: control,
          isThreeLine: isThreeLine,
          dense: dense,
          enabled: onChanged != null,
          onTap: onChanged != null
              ? () {
                  onChanged(!value);
                }
              : null,
          selected: selected,
        ),
      ),
    );
  }
}

正如我在消息来源中所指出的那样,因为它是从颤动源复制的,所以来自源的license at time of copying适用。

答案 1 :(得分:1)

从 Flutter 2 开始,现在有了 SwitchListTile 的 Cupertino 等价物。

您可以组合使用 CupertinoFormSectionCupertinoFormRowCupertinoSwitch 小部件来生成具有 iOS 分段视觉美感的验证表单字段。

CupertinoFormSection(
  header: Text('Section 1'),
  children: <Widget>[
    CupertinoFormRow(
      child: CupertinoSwitch(
        value: toggleValue,
        onChanged: (value) {
          setState(() {
            toggleValue = value;
          });
        },
      ),
      prefix: Text('Toggle 1'),
      helper: Text('Slide me'),
      error: toggleValue ? null : Text('Not slided'),
    ),
    CupertinoFormRow(
      child: CupertinoSwitch(
        value: !toggleValue,
        onChanged: (value) {
          setState(() {
            toggleValue = value;
          });
        },
      ),
      prefix: Text('Toggle 2'),
    ),
  ],
)

Cupertino form with Switch