美文网首页
flutter 自定义高度,圆角,间距的CupertinoSeg

flutter 自定义高度,圆角,间距的CupertinoSeg

作者: 护她此生周全 | 来源:发表于2020-12-09 17:35 被阅读0次

    更改系统源码后的新增了自定义高度和圆角

    源码默认圆角为5,高度为28,构造方法里面没有这些参数

    下图是更改为圆角20,高度50,padding没有用,自己添加margin为10的状态

    image.png

    1.复制下面的代码到一个新的dart文件当中

    
    // Copyright 2014 The Flutter Authors. All rights reserved.
    
    // Use of this source code is governed by a BSD-style license that can be
    
    // found in the LICENSE file.
    
    // @dart = 2.8
    
    import 'dart:collection';
    
    import 'dart:math' as math;
    
    import 'package:flutter/cupertino.dart';
    
    import 'package:flutter/foundation.dart';
    
    import 'package:flutter/rendering.dart';
    
    import 'package:flutter/widgets.dart';
    
    import 'package:people_manager/config/net_config/api.dart';
    
    // Minimum padding from edges of the segmented control to edges of
    
    // encompassing widget.
    
    const EdgeInsetsGeometry _kHorizontalItemPadding =
    
    EdgeInsets.symmetric(horizontal:30.0);
    
    // Minimum height of the segmented control.
    
    // const double _kMinSegmentedControlHeight = 40.0;
    
    // The duration of the fade animation used to transition when a new widget
    
    // is selected.
    
    const Duration _kFadeDuration =Duration(milliseconds:165);
    
    /// An iOS-style segmented control.
    
    ///
    
    /// Displays the widgets provided in the [Map] of [children] in a
    
    /// horizontal list. Used to select between a number of mutually exclusive
    
    /// options. When one option in the segmented control is selected, the other
    
    /// options in the segmented control cease to be selected.
    
    ///
    
    /// A segmented control can feature any [Widget] as one of the values in its
    
    /// [Map] of [children]. The type T is the type of the keys used
    
    /// to identify each widget and determine which widget is selected. As
    
    /// required by the [Map] class, keys must be of consistent types
    
    /// and must be comparable. The ordering of the keys will determine the order
    
    /// of the widgets in the segmented control.
    
    ///
    
    /// When the state of the segmented control changes, the widget calls the
    
    /// [onValueChanged] callback. The map key associated with the newly selected
    
    /// widget is returned in the [onValueChanged] callback. Typically, widgets
    
    /// that use a segmented control will listen for the [onValueChanged] callback
    
    /// and rebuild the segmented control with a new [groupValue] to update which
    
    /// option is currently selected.
    
    ///
    
    /// The [children] will be displayed in the order of the keys in the [Map].
    
    /// The height of the segmented control is determined by the height of the
    
    /// tallest widget provided as a value in the [Map] of [children].
    
    /// The width of each child in the segmented control will be equal to the width
    
    /// of widest child, unless the combined width of the children is wider than
    
    /// the available horizontal space. In this case, the available horizontal space
    
    /// is divided by the number of provided [children] to determine the width of
    
    /// each widget. The selection area for each of the widgets in the [Map] of
    
    /// [children] will then be expanded to fill the calculated space, so each
    
    /// widget will appear to have the same dimensions.
    
    ///
    
    /// A segmented control may optionally be created with custom colors. The
    
    /// [unselectedColor], [selectedColor], [borderColor], and [pressedColor]
    
    /// arguments can be used to override the segmented control's colors from
    
    /// [CupertinoTheme] defaults.
    
    ///
    
    /// See also:
    
    ///
    
    ///  * [CupertinoSegmentedControl], a segmented control widget in the style used
    
    ///    up until iOS 13.
    
    ///  *
    
    class CupertinoSegmentedControlextends StatefulWidget {
    
    /// Creates an iOS-style segmented control bar.
    
    ///
    
      /// The [children] and [onValueChanged] arguments must not be null. The
    
      /// [children] argument must be an ordered [Map] such as a [LinkedHashMap].
    
      /// Further, the length of the [children] list must be greater than one.
    
    ///
    
      /// Each widget value in the map of [children] must have an associated key
    
    /// that uniquely identifies this widget. This key is what will be returned
    
      /// in the [onValueChanged] callback when a new value from the [children] map
    
    /// is selected.
    
    ///
    
      /// The [groupValue] is the currently selected value for the segmented control.
    
      /// If no [groupValue] is provided, or the [groupValue] is null, no widget will
    
      /// appear as selected. The [groupValue] must be either null or one of the keys
    
      /// in the [children] map.
    
      CupertinoSegmentedControl({
    
    Key key,
    
        @required this.children,
    
        @required this.onValueChanged,
    
        this.groupValue,
    
        this.unselectedColor,
    
        this.selectedColor,
    
        this.borderColor,
    
        this.radius =5,
    
        this.kMinSegmentedControlHeight = 30,
    
        this.pressedColor,
    
        this.padding,
    
      })  :assert(children !=null),
    
            assert(children.length >=2),
    
            assert(onValueChanged !=null),
    
            assert(
    
    groupValue ==null ||
    
    children.keys.any((T child) => child == groupValue),
    
              'The groupValue must be either null or one of the keys in the children map.',
    
            ),
    
            super(key: key);
    
      /// The identifying keys and corresponding widget values in the
    
    /// segmented control.
    
    ///
    
    /// The map must have more than one entry.
    
    /// This attribute must be an ordered [Map] such as a [LinkedHashMap].
    
      final Mapchildren;
    
      /// The identifier of the widget that is currently selected.
    
    ///
    
      /// This must be one of the keys in the [Map] of [children].
    
    /// If this attribute is null, no widget will be initially selected.
    
      final TgroupValue;
    
      /// The callback that is called when a new option is tapped.
    
    ///
    
    /// This attribute must not be null.
    
    ///
    
    /// The segmented control passes the newly selected widget's associated key
    
    /// to the callback but does not actually change state until the parent
    
      /// widget rebuilds the segmented control with the new [groupValue].
    
    ///
    
      /// The callback provided to [onValueChanged] should update the state of
    
    /// the parent [StatefulWidget] using the [State.setState] method, so that
    
    /// the parent gets rebuilt; for example:
    
    ///
    
    /// {@tool snippet}
    
    ///
    
    /// ```dart
    
    /// class SegmentedControlExample extends StatefulWidget {
    
    ///  @override
    
    ///  State createState() => SegmentedControlExampleState();
    
    /// }
    
    ///
    
    /// class SegmentedControlExampleState extends State {
    
    ///  final Map children = const {
    
    ///    0: Text('Child 1'),
    
    ///    1: Text('Child 2'),
    
    ///  };
    
    ///
    
    ///  int currentValue;
    
    ///
    
    ///  @override
    
    ///  Widget build(BuildContext context) {
    
    ///    return Container(
    
    ///      child: CupertinoSegmentedControl(
    
    ///        children: children,
    
    ///        onValueChanged: (int newValue) {
    
    ///          setState(() {
    
    ///            currentValue = newValue;
    
    ///          });
    
    ///        },
    
    ///        groupValue: currentValue,
    
    ///      ),
    
    ///    );
    
    ///  }
    
    /// }
    
    /// ```
    
    /// {@end-tool}
    
      final ValueChangedonValueChanged;
    
      /// The color used to fill the backgrounds of unselected widgets and as the
    
    /// text color of the selected widget.
    
    ///
    
    /// Defaults to [CupertinoTheme]'s `primaryContrastingColor` if null.
    
      final ColorunselectedColor;
    
      /// The color used to fill the background of the selected widget and as the text
    
    /// color of unselected widgets.
    
    ///
    
    /// Defaults to [CupertinoTheme]'s `primaryColor` if null.
    
      final ColorselectedColor;
    
      /// The color used as the border around each widget.
    
    ///
    
    /// Defaults to [CupertinoTheme]'s `primaryColor` if null.
    
      final ColorborderColor;
    
      /// The color used to fill the background of the widget the user is
    
    /// temporarily interacting with through a long press or drag.
    
    ///
    
    /// Defaults to the selectedColor at 20% opacity if null.
    
      final ColorpressedColor;
    
      /// The CupertinoSegmentedControl will be placed inside this padding.
    
    ///
    
    /// Defaults to EdgeInsets.symmetric(horizontal: 16.0)
    
      final EdgeInsetsGeometrypadding;
    
      final doubleradius;
    
      final doublekMinSegmentedControlHeight;
    
      @override
    
      _SegmentedControlStatecreateState() =>_SegmentedControlState();
    
    }
    
    class _SegmentedControlStateextends State>
    
    with TickerProviderStateMixin> {
    
    T_pressedKey;
    
      final List_selectionControllers =
    
    [];
    
      final List_childTweens = [];
    
      ColorTween_forwardBackgroundColorTween;
    
      ColorTween_reverseBackgroundColorTween;
    
      ColorTween_textColorTween;
    
      Color_selectedColor;
    
      Color_unselectedColor;
    
      Color_borderColor;
    
      double_radius;
    
      Color_pressedColor;
    
      double_kMinSegmentedControlHeight;
    
      AnimationControllercreateAnimationController() {
    
    return AnimationController(
    
    duration: _kFadeDuration,
    
          vsync:this,
    
        )..addListener(() {
    
    setState(() {
    
    // State of background/text colors has changed
    
            });
    
          });
    
      }
    
    bool_updateColors() {
    
    assert(mounted, 'This should only be called after didUpdateDependencies');
    
        bool changed =false;
    
        final Color selectedColor =
    
    widget.selectedColor ?? CupertinoTheme.of(context).primaryColor;
    
        if (_selectedColor != selectedColor) {
    
    changed =true;
    
          _selectedColor = selectedColor;
    
        }
    
    final Color unselectedColor =widget.unselectedColor ??
    
    CupertinoTheme.of(context).primaryContrastingColor;
    
        if (_unselectedColor != unselectedColor) {
    
    changed =true;
    
          _unselectedColor = unselectedColor;
    
        }
    
    final Color borderColor =
    
    widget.borderColor ?? CupertinoTheme.of(context).primaryColor;
    
        if (_borderColor != borderColor) {
    
    changed =true;
    
          _borderColor = borderColor;
    
        }
    
    _radius =widget.radius;
    
        _kMinSegmentedControlHeight =widget.kMinSegmentedControlHeight;
    
        final Color pressedColor =widget.pressedColor ??
    
    CupertinoTheme.of(context).primaryColor.withOpacity(0.2);
    
        if (_pressedColor != pressedColor) {
    
    changed =true;
    
          _pressedColor = pressedColor;
    
        }
    
    _forwardBackgroundColorTween =ColorTween(
    
    begin:_pressedColor,
    
          end:_selectedColor,
    
        );
    
        _reverseBackgroundColorTween =ColorTween(
    
    begin:_unselectedColor,
    
          end:_selectedColor,
    
        );
    
        _textColorTween =ColorTween(
    
    begin:_selectedColor,
    
          end:_unselectedColor,
    
        );
    
        return changed;
    
      }
    
    void _updateAnimationControllers() {
    
    assert(mounted, 'This should only be called after didUpdateDependencies');
    
        for (final AnimationController controllerin _selectionControllers) {
    
    controller.dispose();
    
        }
    
    _selectionControllers.clear();
    
        _childTweens.clear();
    
        for (final T keyin widget.children.keys) {
    
    final AnimationController animationController =
    
    createAnimationController();
    
          if (widget.groupValue == key) {
    
    _childTweens.add(_reverseBackgroundColorTween);
    
            animationController.value =1.0;
    
          }else {
    
    _childTweens.add(_forwardBackgroundColorTween);
    
          }
    
    _selectionControllers.add(animationController);
    
        }
    
    }
    
    @override
    
      void didChangeDependencies() {
    
    super.didChangeDependencies();
    
        if (_updateColors()) {
    
    _updateAnimationControllers();
    
        }
    
    }
    
    @override
    
      void didUpdateWidget(CupertinoSegmentedControl oldWidget) {
    
    super.didUpdateWidget(oldWidget);
    
        if (_updateColors() ||
    
    oldWidget.children.length !=widget.children.length) {
    
    _updateAnimationControllers();
    
        }
    
    if (oldWidget.groupValue !=widget.groupValue) {
    
    int index =0;
    
          for (final T keyin widget.children.keys) {
    
    if (widget.groupValue == key) {
    
    _childTweens[index] =_forwardBackgroundColorTween;
    
              _selectionControllers[index].forward();
    
            }else {
    
    _childTweens[index] =_reverseBackgroundColorTween;
    
              _selectionControllers[index].reverse();
    
            }
    
    index +=1;
    
          }
    
    }
    
    }
    
    @override
    
      void dispose() {
    
    for (final AnimationController animationController
    
    in _selectionControllers) {
    
    animationController.dispose();
    
        }
    
    super.dispose();
    
      }
    
    void _onTapDown(T currentKey) {
    
    if (_pressedKey ==null && currentKey !=widget.groupValue) {
    
    setState(() {
    
    _pressedKey = currentKey;
    
          });
    
        }
    
    }
    
    void _onTapCancel() {
    
    setState(() {
    
    _pressedKey =null;
    
        });
    
      }
    
    void _onTap(T currentKey) {
    
    if (currentKey !=_pressedKey)return;
    
        if (currentKey !=widget.groupValue) {
    
    widget.onValueChanged(currentKey);
    
        }
    
    _pressedKey =null;
    
      }
    
    ColorgetTextColor(int index, T currentKey) {
    
    if (_selectionControllers[index].isAnimating)
    
    return _textColorTween.evaluate(_selectionControllers[index]);
    
        if (widget.groupValue == currentKey)return _unselectedColor;
    
        return _selectedColor;
    
      }
    
    ColorgetBackgroundColor(int index, T currentKey) {
    
    if (_selectionControllers[index].isAnimating)
    
    return _childTweens[index].evaluate(_selectionControllers[index]);
    
        if (widget.groupValue == currentKey)return _selectedColor;
    
        if (_pressedKey == currentKey)return _pressedColor;
    
        return _unselectedColor;
    
      }
    
    @override
    
      Widgetbuild(BuildContext context) {
    
    final List _gestureChildren = [];
    
        final List _backgroundColors = [];
    
        int index =0;
    
        int selectedIndex;
    
        int pressedIndex;
    
        for (final T currentKeyin widget.children.keys) {
    
    selectedIndex = (widget.groupValue == currentKey) ? index : selectedIndex;
    
          pressedIndex = (_pressedKey == currentKey) ? index : pressedIndex;
    
          final TextStyle textStyle = DefaultTextStyle.of(context).style.copyWith(
    
    color: getTextColor(index, currentKey),
    
              );
    
          final IconThemeData iconTheme =IconThemeData(
    
    color: getTextColor(index, currentKey),
    
          );
    
          Widget child =Center(
    
    child:widget.children[currentKey],
    
          );
    
          child =GestureDetector(
    
    behavior: HitTestBehavior.opaque,
    
            onTapDown: (TapDownDetails event) {
    
    _onTapDown(currentKey);
    
            },
    
            onTapCancel: _onTapCancel,
    
            onTap: () {
    
    _onTap(currentKey);
    
            },
    
            child:IconTheme(
    
    data: iconTheme,
    
              child:DefaultTextStyle(
    
    style: textStyle,
    
                child:Semantics(
    
    button:true,
    
                  inMutuallyExclusiveGroup:true,
    
                  selected:widget.groupValue == currentKey,
    
                  child: child,
    
                ),
    
              ),
    
            ),
    
          );
    
          _backgroundColors.add(getBackgroundColor(index, currentKey));
    
          _gestureChildren.add(child);
    
          index +=1;
    
        }
    
    final Widget box =_SegmentedControlRenderWidget(
    
    children: _gestureChildren,
    
            selectedIndex: selectedIndex,
    
            pressedIndex: pressedIndex,
    
            backgroundColors: _backgroundColors,
    
            borderColor:_borderColor,
    
            radius:_radius,
    
            kMinSegmentedControlHeight:_kMinSegmentedControlHeight);
    
        return Padding(
    
    padding:widget.padding ?? _kHorizontalItemPadding,
    
          child:UnconstrainedBox(
    
    constrainedAxis: Axis.horizontal,
    
            child: box,
    
          ),
    
        );
    
      }
    
    }
    
    class _SegmentedControlRenderWidgetextends MultiChildRenderObjectWidget {
    
    _SegmentedControlRenderWidget(
    
    {Key key,
    
          List children =const [],
    
          @required this.selectedIndex,
    
          @required this.pressedIndex,
    
          @required this.backgroundColors,
    
          @required this.borderColor,
    
          @required this.radius,
    
          @required this.kMinSegmentedControlHeight})
    
    :super(
    
    key: key,
    
              children: children,
    
            );
    
      final intselectedIndex;
    
      final intpressedIndex;
    
      final ListbackgroundColors;
    
      final ColorborderColor;
    
      final doubleradius;
    
      final doublekMinSegmentedControlHeight;
    
      @override
    
      RenderObjectcreateRenderObject(BuildContext context) {
    
    return _RenderSegmentedControl(
    
    textDirection: Directionality.of(context),
    
            selectedIndex:selectedIndex,
    
            pressedIndex:pressedIndex,
    
            backgroundColors:backgroundColors,
    
            borderColor:borderColor,
    
            radius:radius,
    
            kMinSegmentedControlHeight:kMinSegmentedControlHeight);
    
      }
    
    @override
    
      void updateRenderObject(
    
    BuildContext context, _RenderSegmentedControl renderObject) {
    
    renderObject
    
    ..textDirection = Directionality.of(context)
    
    ..selectedIndex =selectedIndex
    
          ..pressedIndex =pressedIndex
    
          ..backgroundColors =backgroundColors
    
          ..borderColor =borderColor;
    
      }
    
    }
    
    class _SegmentedControlContainerBoxParentData
    
    extends ContainerBoxParentData {
    
    RRectsurroundingRect;
    
    }
    
    typedef _NextChild = RenderBox Function(RenderBox child);
    
    class _RenderSegmentedControlextends RenderBox
    
    with
    
            ContainerRenderObjectMixin
    
                ContainerBoxParentData>,
    
            RenderBoxContainerDefaultsMixin
    
                ContainerBoxParentData> {
    
    _RenderSegmentedControl({
    
    @required int selectedIndex,
    
        @required int pressedIndex,
    
        @required TextDirection textDirection,
    
        @required List backgroundColors,
    
        @required Color borderColor,
    
        @required double radius,
    
        @required double kMinSegmentedControlHeight,
    
      })  :assert(textDirection !=null),
    
            _textDirection = textDirection,
    
            _selectedIndex = selectedIndex,
    
            _pressedIndex = pressedIndex,
    
            _backgroundColors = backgroundColors,
    
            _borderColor = borderColor,
    
            _radius = radius,
    
            _kMinSegmentedControlHeight = kMinSegmentedControlHeight;
    
      intget selectedIndex =>_selectedIndex;
    
      int_selectedIndex;
    
      set selectedIndex(int value) {
    
    if (_selectedIndex == value) {
    
    return;
    
        }
    
    _selectedIndex = value;
    
        markNeedsPaint();
    
      }
    
    intget pressedIndex =>_pressedIndex;
    
      int_pressedIndex;
    
      set pressedIndex(int value) {
    
    if (_pressedIndex == value) {
    
    return;
    
        }
    
    _pressedIndex = value;
    
        markNeedsPaint();
    
      }
    
    TextDirectionget textDirection =>_textDirection;
    
      TextDirection_textDirection;
    
      set textDirection(TextDirection value) {
    
    if (_textDirection == value) {
    
    return;
    
        }
    
    _textDirection = value;
    
        markNeedsLayout();
    
      }
    
    Listget backgroundColors =>_backgroundColors;
    
      List_backgroundColors;
    
      set backgroundColors(List value) {
    
    if (_backgroundColors == value) {
    
    return;
    
        }
    
    _backgroundColors = value;
    
        markNeedsPaint();
    
      }
    
    Colorget borderColor =>_borderColor;
    
      Color_borderColor;
    
      set borderColor(Color value) {
    
    if (_borderColor == value) {
    
    return;
    
        }
    
    _borderColor = value;
    
        markNeedsPaint();
    
      }
    
    doubleget radius =>_radius;
    
      double_radius;
    
      set radius(double value) {
    
    if (_radius == value) {
    
    return;
    
        }
    
    _radius = value;
    
        markNeedsPaint();
    
      }
    
    doubleget kMinSegmentedControlHeight =>_kMinSegmentedControlHeight;
    
      double_kMinSegmentedControlHeight;
    
      set kMinSegmentedControlHeight(double value) {
    
    if (_kMinSegmentedControlHeight == value) {
    
    return;
    
        }
    
    _kMinSegmentedControlHeight = value;
    
        markNeedsPaint();
    
      }
    
    @override
    
      doublecomputeMinIntrinsicWidth(double height) {
    
    RenderBox child =firstChild;
    
        double minWidth =0.0;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          final double childWidth = child.getMinIntrinsicWidth(height);
    
          minWidth = math.max(minWidth, childWidth);
    
          child = childParentData.nextSibling;
    
        }
    
    return minWidth *childCount;
    
      }
    
    @override
    
      doublecomputeMaxIntrinsicWidth(double height) {
    
    RenderBox child =firstChild;
    
        double maxWidth =0.0;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          final double childWidth = child.getMaxIntrinsicWidth(height);
    
          maxWidth = math.max(maxWidth, childWidth);
    
          child = childParentData.nextSibling;
    
        }
    
    return maxWidth *childCount;
    
      }
    
    @override
    
      doublecomputeMinIntrinsicHeight(double width) {
    
    RenderBox child =firstChild;
    
        double minHeight =0.0;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          final double childHeight = child.getMinIntrinsicHeight(width);
    
          minHeight = math.max(minHeight, childHeight);
    
          child = childParentData.nextSibling;
    
        }
    
    return minHeight;
    
      }
    
    @override
    
      doublecomputeMaxIntrinsicHeight(double width) {
    
    RenderBox child =firstChild;
    
        double maxHeight =0.0;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          final double childHeight = child.getMaxIntrinsicHeight(width);
    
          maxHeight = math.max(maxHeight, childHeight);
    
          child = childParentData.nextSibling;
    
        }
    
    return maxHeight;
    
      }
    
    @override
    
      doublecomputeDistanceToActualBaseline(TextBaseline baseline) {
    
    return defaultComputeDistanceToHighestActualBaseline(baseline);
    
      }
    
    @override
    
      void setupParentData(RenderBox child) {
    
    if (child.parentData is! _SegmentedControlContainerBoxParentData) {
    
    child.parentData =_SegmentedControlContainerBoxParentData();
    
        }
    
    }
    
    void _layoutRects(
    
    _NextChild nextChild, RenderBox leftChild, RenderBox rightChild) {
    
    RenderBox child = leftChild;
    
        double start =0.0;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          final Offset childOffset =Offset(start, 0.0);
    
          childParentData.offset = childOffset;
    
          final Rect childRect =
    
    Rect.fromLTWH(start, 0.0, child.size.width, child.size.height);
    
          RRect rChildRect;
    
          if (child == leftChild) {
    
    rChildRect =RRect.fromRectAndCorners(childRect,
    
                topLeft:Radius.circular(radius),
    
                bottomLeft:Radius.circular(radius));
    
          }else if (child == rightChild) {
    
    rChildRect =RRect.fromRectAndCorners(childRect,
    
                topRight:Radius.circular(radius),
    
                bottomRight:Radius.circular(radius));
    
          }else {
    
    rChildRect =RRect.fromRectAndCorners(childRect);
    
          }
    
    childParentData.surroundingRect = rChildRect;
    
          start += child.size.width;
    
          child = nextChild(child);
    
        }
    
    }
    
    @override
    
      void performLayout() {
    
    final BoxConstraints constraints =this.constraints;
    
        double maxHeight =_kMinSegmentedControlHeight;
    
        double childWidth = constraints.minWidth /childCount;
    
        for (final RenderBox childin getChildrenAsList()) {
    
    childWidth =
    
    math.max(childWidth, child.getMaxIntrinsicWidth(double.infinity));
    
        }
    
    childWidth = math.min(childWidth, constraints.maxWidth /childCount);
    
        RenderBox child =firstChild;
    
        while (child !=null) {
    
    final double boxHeight = child.getMaxIntrinsicHeight(childWidth);
    
          maxHeight = math.max(maxHeight, boxHeight);
    
          child = childAfter(child);
    
        }
    
    constraints.constrainHeight(maxHeight);
    
        final BoxConstraints childConstraints =BoxConstraints.tightFor(
    
    width: childWidth,
    
          height: maxHeight,
    
        );
    
        child =firstChild;
    
        while (child !=null) {
    
    child.layout(childConstraints, parentUsesSize:true);
    
          child = childAfter(child);
    
        }
    
    switch (textDirection) {
    
    case TextDirection.rtl:
    
    _layoutRects(
    
    childBefore,
    
              lastChild,
    
              firstChild,
    
            );
    
    break;
    
          case TextDirection.ltr:
    
    _layoutRects(
    
    childAfter,
    
              firstChild,
    
              lastChild,
    
            );
    
    break;
    
        }
    
    size = constraints.constrain(Size(childWidth *childCount, maxHeight));
    
      }
    
    @override
    
      void paint(PaintingContext context, Offset offset) {
    
    RenderBox child =firstChild;
    
        int index =0;
    
        while (child !=null) {
    
    _paintChild(context, offset, child, index);
    
          child = childAfter(child);
    
          index +=1;
    
        }
    
    }
    
    void _paintChild(
    
    PaintingContext context, Offset offset, RenderBox child, int childIndex) {
    
    assert(child !=null);
    
        final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
        context.canvas.drawRRect(
    
    childParentData.surroundingRect.shift(offset),
    
          Paint()
    
    ..color =backgroundColors[childIndex]
    
    ..style = PaintingStyle.fill,
    
        );
    
        context.canvas.drawRRect(
    
    childParentData.surroundingRect.shift(offset),
    
          Paint()
    
    ..color =borderColor
    
            ..strokeWidth =1.0
    
            ..style = PaintingStyle.stroke,
    
        );
    
        context.paintChild(child, childParentData.offset + offset);
    
      }
    
    @override
    
      boolhitTestChildren(BoxHitTestResult result, {@required Offset position}) {
    
    assert(position !=null);
    
        RenderBox child =lastChild;
    
        while (child !=null) {
    
    final _SegmentedControlContainerBoxParentData childParentData =
    
    child.parentData as _SegmentedControlContainerBoxParentData;
    
          if (childParentData.surroundingRect.contains(position)) {
    
    return result.addWithPaintOffset(
    
    offset: childParentData.offset,
    
              position: position,
    
              hitTest: (BoxHitTestResult result, Offset localOffset) {
    
    assert(localOffset == position - childParentData.offset);
    
                return child.hitTest(result, position: localOffset);
    
              },
    
            );
    
          }
    
    child = childParentData.previousSibling;
    
        }
    
    return false;
    
      }
    
    }
    
    

    2.引用修改过得文件和组件,准备需要的数据,下面之所以用到用container包裹是因为我发现直接设置padding没有效果,只能靠中间的文字设置margin才能起到padding的作用

    
    import 'package:people_manager/widget/segment_widget.dart' as sement;
    
    //避免和系统组件冲突,因为名字一样
    
    //下面是所需要的数据
    
    Map<String, Container> map = {```
    
    '0':Container(
    
    decoration:BoxDecoration(borderRadius:BorderRadius.circular(20.0)),
    
        margin:EdgeInsets.symmetric(horizontal:20.0),
    
        child:Text('Apple'),
    
      ),
    
      '1':Container(
    
    decoration:BoxDecoration(borderRadius:BorderRadius.circular(20.0)),
    
        margin:EdgeInsets.symmetric(horizontal:20.0),
    
        child:Text('Orange'),
    
      )
    
    };
    
    static String_fruit ='0';
    
    

    主要使用代码

    sement.CupertinoSegmentedControl(
                                      kMinSegmentedControlHeight: 50,
                          radius: 20,
                          children: map,
                          // 数据
                          groupValue: _fruit,
                          // 选中的数据
                          onValueChanged: (fruit) {
                            setState(() {
                              // 数据改变时通过setState改变选中状态
                              _fruit = fruit;
                            });
                          },
                          unselectedColor: CupertinoColors.white,
                          // 未选中颜色
                          selectedColor: CupertinoColors.activeBlue,
                          // 选中颜色
                          borderColor: CupertinoColors.activeBlue,
                          // 边框颜色
                          pressedColor: const Color(0x33007AFF), // 点击时候的颜色
                        )
    

    相关文章

      网友评论

          本文标题:flutter 自定义高度,圆角,间距的CupertinoSeg

          本文链接:https://www.haomeiwen.com/subject/tvnhgktx.html