“This is the 27th day of my participation in the August Gwen Challenge, for more details: August Gwen Challenge” juejin.cn/post/698796…

Buttons are essential in daily life. I have tried different types of buttons and customized them according to requirements. Today, I will study the most basic Button in the system of small dishes.

There are no Button widgets in Flutter, but many different types of Child Button widgets are available. The whole source code can be divided into RawMaterialButton and IconButton two categories;

RaisedButton/FlatButton/OutlineButton inherits from MaterialButton and The MaterialButton is the encapsulation of RawMaterialButton. BackButton/CloseButton/PopupMenuButton inherits from IconButton; Finally, RawMaterialButton and IconButton are filled and drawn by ConstrainedBox.

IconButton series

IconButton series belongs to the IconButton, relatively simple to use; Its core is InkResponse water ripple effect;

IconButton

Source code analysis
Const IconButton({Key Key, this.iconSize = 24.0, this.padding = const edgeinsets.all (8.0), This.center, // icon position @required this.icon, // Icon resource this.color, // this. HighlightColor, // click the highlightColor this.splashColor, // water ripple color this.disabledColor, // Highlight color when not clickable @required this.onpressed, this.tooltip // long press prompt})Copy the code

Analyze the source code, where icon and onPressed are required and the rest of the properties are adjusted as required;

Case try
  1. Small dishes first try the most basic IconButton; Long press to be reminded by the tooltip, and click on the default theme color;
IconButton(icon: Icon(Icons.android), tooltip: 'IconButton tootip1',
    onPressed: () => Toast.show('IconButton', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM));
Copy the code
  1. Side dish tries a few of these attributes; The icon color is Cyan, the background color is deepPurple, and the water ripple color is redAccent. Note that the color attribute does not take effect when the icon itself is set to a color.
IconButton(icon: Icon(Icons.android), tooltip: 'IconButton tootip2', color: Colors.cyan, highlightColor: Colors. DeepPurple. WithOpacity (0.4), splashColor: Colors. RedAccent, onPressed: () => Toast.show('IconButton', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM));Copy the code
  1. Small dishes try not to click when icon color is disabledColor set to green; Also if icon itself is set to color, disabledColor does not take effect. Note: onPressed: null is different from onPressed: ()=> null, which represents a no-click event; The latter represents a click event, but click without action;
IconButton(icon: Icon(Icons.android), disabledColor: Colors.green, onPressed: null);
Copy the code
  1. Icon is Widget, icon/Image/ImageIcon, etc.
IconButton(icon: image. asset('images/ic_launcher. PNG '), iconSize: 40.0, onPressed: null);Copy the code

BackButton

BackButton is very specific, usually used to return to the previous page;

Source code analysis
const BackButton({ Key key, this.color })
Copy the code

Analysis of the source code, BackButton inherited from IconButton, only allow to set icon color, icon style Android and iOS is different and can not be modified; Click to determine whether maybePop can return to the previous page;

Case try
BackButton();
BackButton(color: Colors.green);
Copy the code

CloseButton

CloseButton is usually used as a CloseButton in the navigation bar similar to BackButton;

Source code analysis
const CloseButton({ Key key }) : super(key: key);
Copy the code

Source code analysis, CloseButton inherited from IconButton, no need to set any attributes; Click to determine whether maybePop can return to the previous page;

Case try
CloseButton();
Copy the code

RawMaterialButton series

RawMaterialButton

RawMaterialButton is the basis of MaterialButton. Its core is composed of Material and InkWell, etc. However, the current Theme or ButtonTheme cannot be used to calculate the default value of an unspecified parameter;

Source code analysis
Const RawMaterialButton({Key Key, @required this.onPressed, this.onHighlightChanged, // highlight the changed callback this.textStyle, // text attribute this.fillColor, // fillColor this.highlightColor, // background highlightColor this.splashColor, // water color this.elevation = 2.0, // Shadow this.highlightElevation = 8.0, // Shadow this.disabledElevation = 0.0, // shadow this.padding = EdgeInsets. Zero, // This. Constraints = const BoxConstraints(minWidth: 88.0, minHeight: This.shape = const roundedBorder (), // This.animationDuration = kThemeChangeDuration, This.clipbehavior = clip. none, // MaterialTapTargetSize MaterialTapTargetSize, This.child,})Copy the code

According to the source code analysis, RawMaterialButton does not have width and height properties. The position and size can be adjusted according to the padding or outer layer depending on the Container. The default minimum size is 88px by 36px.

Case try

The small dish defines a basic button, and listens to its highlight changes when the state, and our common button is basically the same;

RawMaterialButton(padding: EdgeInsets. All (20.0), child: Row(mainAxisSize: mainAxisSize. Min, children: <Widget>[Padding(child: Icon(Icons. Android), Padding: EdgeInsets. Only (right: 10.0)), Text('RawMaterialButton', style: Color: color.pink, fontSize: 18.0, fillColor: color.pink, color.pink, color.pink, color.pink, color.pink Colors. GreenAccent. WithOpacity (0.4), highlightColor: Colors. Cyan, splashColor: Colors. DeepPurple. WithOpacity (0.4), onPressed: () = > Toast. The show (' RawMaterialButton, context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM), onHighlightChanged: (state) => Toast.show('onHighlightChanged -> $state', context, duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER))Copy the code

FloatingActionButton

FloatingActionButton is a wrapper of RawMaterialButton that floats above the content of the screen, usually at the bottom, left, right corner or in the middle. There is usually only one page;

Source code analysis
Const FloatingActionButton({Key Key, this.child, this.tooltip, const FloatingActionButton({Key Key, this.child, this.tooltip, HeroTag = const _DefaultHeroTag(), // Hero animation tag this.elevation = 6.0, // Shadow this.highlightElevation = 12.0, // Shadow @required this.onPressed, this.mini = false, // size size, Default this.shape = const CircleBorder(), // This.clipBehavior = clip.None, Shear effect this. / / anti-aliasing materialTapTargetSize, / / click target minimal size enclosing isExtended = false,. / / whether to adopt the extended way})Copy the code
Case try
  1. The side dish tries a basic FloatingActionButton; A long press will give you a tooltip;
floatingActionButton: FloatingActionButton(child: Icon(Icons.android), tooltip: 'FloatingActionButton ToolTip',
    onPressed: () => Toast.show('FloatingActionButton', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM));
Copy the code

  1. ForegroundColor is the color of the child element on the button layer. If the child element itself is set to a color, it will not take effect. BackgroundColor is the backgroundColor of the button;
ForegroundColor: Colors. RedAccent. WithOpacity (0.7), backgroundColor: Colors. Green. WithOpacity (0.4),Copy the code

  1. Elevation button default shadow height, namely z axis height; HighlightElevation is the shadow height when the highlight is clicked;
Elevation: 0.0, highlightElevation: 10.0,Copy the code

  1. Whether mini is displayed in small size mode; The materialTapTargetSize section (section 4.1) is the minimum hit size of the configuration target, present the default 48px * 48px recommended Android size; ShrinkWrap to shrink to the minimum size provided by Material;
mini: true,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
Copy the code

  1. Shape is the size of the style; ClipBehavior is anti-aliasing effect;
Shape: rectangleBorder (borderRadius: borderRadius. All (Radius. Circular (14.0))), clipBehavior: clip.antialias,Copy the code

  1. HeroTag animation label, the default is FloatingActionButtonAnimator. Scaling; HeroTag is the same by default and can be customized as a unique tag. Set the previous page to the same heroTag as the current page FloatingActionButton;
floatingActionButtonAnimator: MyAnimation(), heroTag: "aceTag", class MyAnimation extends FloatingActionButtonAnimator { double _x, _y; @override Offset getOffset({Offset begin, Offset end, double progress}) { _x = begin.dx + (end.dx - begin.dx) * progress; _y = begin.dy + (end.dy - begin.dy) * progress; Return Offset(_x * 0.5, _y * 0.9); } override Animation<double> getRotationAnimation({Animation<double> parent}) {return Tween<double>(begin: 1.0, end: 1.0). The animate (parent); } override Animation<double> getScaleAnimation({Animation<double> parent}) {return Tween<double>(begin: 1.0, end: 1.0). The animate (parent); }}Copy the code

  1. FloatingActionButton provides. Extended mode to create non-square button styles representing label styles; Other attributes have no difference;
floatingActionButton: FloatingActionButton.extended(
    onPressed: () => Toast.show('FloatingActionButton.extended', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM),
    icon: Icon(Icons.android),
    label: Text('Android'));
Copy the code

  1. The size of FloatingActionButton display may vary for specific personalization; The side dish tried several ways;

A. Implement FloatingActionButton through the basic RawMaterialButton, and add the Container constraint size to the outer layer; Side dish comparison recommended method 1, higher flexibility;

/ / a floatingActionButton: Container (width: 100.0, height: 100.0, color: Colors. GreenAccent. WithOpacity (0.4), the child: RawMaterialButton(Shape: CircleBorder(), elevation: 0.0, Child: Icon(Icons.android), onPressed: () {})Copy the code

B. Use FittedBox to enlarge the button to the Container constraint;

FloatingActionButton: Container(width: 100.0, height: 100.0, Child: FittedBox(child: FloatingActionButton(child: Icon(Icons.android), onPressed: () {})))Copy the code

C. SizeBox has different constraints from FittedBox, except that the overall range is larger and its internal buttons are displayed in a Material suggested style;

SizedBox(Width: 100.0, height: 100.0, Child: floatingActionButton (child: Icon(Icons.android), onPressed: () {}))Copy the code

D. Scale is similar to FittedBox.

Scale (scale: 1.5, child: floatingActionButton (child: Icon(Icons.android), onPressed: () {}))Copy the code


Button involves a lot of content and has strong expansibility. The small dishes are divided into two sections to try to learn. Some understanding may not be in place, there is a problem please guide!

Source: Little Monk A Ce