Widget

Everything in Flutter is a Widget. Widgets are the basic building blocks of the Flutter application interface. Each Widget is closely related to the final user interface presentation.

A widget can be defined as follows:

  • A structural element (a button, a menu)
  • A style element (font, color scheme, etc.)
  • Layout (padding, margin)
  • , etc.

What is a widget

abstract class Widget extends DiagnosticableTree { const Widget({ this.key }); final Key key; @protected @factory Element createElement(); static bool canUpdate(Widget oldWidget, Widget newWidget) { return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; }}Copy the code
  • Widget is an abstract class
  • Where canUpdate() determines whether to redraw

Classification of the widget

StatelessWidget key code

There is no internal save state, and the UI does not change after it is created

abstract class StatelessWidget extends Widget {
  const StatelessWidget({ Key key }) : super(key: key);
  @override
  StatelessElement createElement() => StatelessElement(this);
  @protected
  Widget build(BuildContext context);
}
Copy the code

StateFullWidget

It saves the state internally, it calls setState, it becomes UI

abstract class StatefulWidget extends Widget {
  const StatefulWidget({ Key key }) : super(key: key);
  @override
  StatefulElement createElement() => StatefulElement(this);
  
  @protected
  @factory
  State createState();
}
Copy the code

State

The key code

abstract class State<T extends StatefulWidget> with Diagnosticable { T get widget => _widget; T _widget; BuildContext get context => _element; StatefulElement _element; bool get mounted => _element ! = null; @protected @mustCallSuper void initState() { } @mustCallSuper @protected void didUpdateWidget(covariant T oldWidget) { }  @protected @mustCallSuper void reassemble() { } @protected void setState(VoidCallback fn) { final dynamic result = fn()  as dynamic; _element.markNeedsBuild(); } @protected @mustCallSuper void deactivate() { } @protected @mustCallSuper void dispose() { } @protected Widget build(BuildContext context); @protected @mustCallSuper void didChangeDependencies() { } }Copy the code

State lifecycle

  • InitState (): called once when inserted into the widget tree
  • DidChangeDependencies (): called when the state object’s dependencies change
  • Build (): called when building widgets
  • DidUpdateWidget (): Called when the widget is rebuilt
  • Deactivate (): called when the state object is removed from the tree
  • Dispose (): Called when a state object is permanently removed from the tree, usually in this method resources are released

Widget&Element&RenderObject

  • Widgets describe the configuration required for an Element, create it, and determine whether it needs to be updated
  • Element represents an instance of a widget at a specific location in the widget configuration tree, holds both the Widget and renderObject, and is responsible for managing widget configuration and RenderObject rendering
  • Renderobject represents an object in the rendering tree that does the actual rendering work, such as measuring, positioning, drawing, etc

Flutter is commonly used as a base component

Commonly used StatelessWidget

Text

  • Text display control
_buildText() {TextStyle style = TextStyle(color: color.green,// text color fontSize: 20,// text size fontStyle: Italic,// Set italic fontWeight: fontweight.bold); // set bold return Text(" I am a Text ", style: style); }Copy the code

Container

  • Container layout, commonly used to set margins, backgrounds, rounded corners, and other effects for child widgets
_buildContainer() {return Container(alignment: align.center,// align the padding: edgeinsets.all (10),// set the inner margin margin margin: EdgeInsets. Only (left: 20, right: 20),// set decoration: BoxDecoration(// set decoration color: Colors. GreenAccent,// Set the color borderRadius: Borderradio.all (radio.circular (5)),// Set the rounded corner gradient: LinearGradient(Colors: [colors.deeppurple, colors.pinkaccent])),// Set gradient background child: _buildText(),); }Copy the code

Icon Icon

  • An Icon can be a vector, so you can set the size and color
_buildIcon() {return Icon(Icons. Android,// Icons source size: 50, // size color: Colors. }Copy the code

CloseButton&BackButton

 CloseButton(),
 BackButton()
Copy the code

Chip

  • Material design widgets
_buildChip() {return Chip(backgroundColor: Colors. GreenAccent,// backgroundColor avatar: Icon(Icons. Phonelink_off_rounded,color: Color.pink,),// label: Text(' I am Chip's Text '),// labelPadding: EdgeInsets. Only (left: 20),// Margin: TextStyle(color: color.white, fontSize: 10),// TextStyle(EdgeInsets). Only (left: 10, right: 10, top: 5, bottom: 10) 5),//Chip inner margin elevation: 5,); }Copy the code

Divider

  • The divider widget
_buildDivider() {return Divider(height: 50,// Divider height: 5,// Divider height: 20,// left margin: 20,// color: color.blue,// color); }Copy the code

Card

  • Card widget, often used in layout
_buildCart() {return Card(margin: EdgeInsets. All (10),// Card color: Colors. GreenAccent,// background color: Colors. Colors. PinkAccent,// elevation: 5,// RectangleBorder: rectangleborder: rectangleborder: rectangleborder: rectangleborder: rectangleborder Borderradius.all (radius.circular (6.0))// Sets the size of the rounded corner), child: Container(padding: EdgeInsets. Only (left: 10, top: 5, right: 10, bottom: 5), child: _buildText(), )); }Copy the code

AlterDialog

  • Popup window
_buildRaisedButton(BuildContext context) {return RaisedButton(onPressed: () {showDialog(// display the context: context, builder: (context) { return _buildAlterDialog(context); }); }, child: Text(' display box ')); } AlertDialog _buildAlterDialog(BuildContext context) {return AlertDialog(title: Text(' I am the title '), content: FlatButton(onPressed: () {navigator.of (context).pop(); // Close the popbox}, child: Text(" confirm ")],); }Copy the code

FloatingActionButton

  • Also a widget under Material
_buildFloatingActionButton() {
  return FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  );
}
Copy the code

Column&Row

  • Vertical container layout, similar to Linerlayout in Android

Colum has the concept of axis and cross axis,Column is vertical layout, its axis is vertical, cross axis is horizontal; Row is laid out horizontally, its main axis is horizontal, and its cross axis is vertical

_buildColumn() { return Column( mainAxisSize: MainAxisSize. Max, // The size of the main axis // the position of the main axis,Column is the vertical layout, so the vertical direction is the main axis mainAxisAlignment: MainAxisAlignment. Start, // Cross the axis position from the top, and cross the axis with the spindle, also in the horizontal direction () crossAxisAlignment: CrossAxisAlignment. End, horizontal children: / / / / / fill the child widgets _buildText (), _buildText (),],); }Copy the code

Commonly used StatefulWidget

Image

  • Picture control, you can display network pictures and project resource pictures
Image.network( 'https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/96119b38be4be1dafc95fcbff0d9ee30~300x300.image', fit: Boxfit.cover,// Fill method, similar to Android scaleType method width: 60, height: 60,)Copy the code

TextField

  • Text input component
TextField(maxLength: 11,// maximum length keyboardType: TextInputType. Number,// input keyboardType // obscureText: If true, / / clear display inputFormatters: FilteringTextInputFormatter. DigitsOnly / / input type, textInputAction: TextInputAction. Search, / / keyboard text and the bottom right hand corner controller: TextEditingController (text: '86'), / / the default text decoration: InputDecoration(contentPadding: EdgeInsets. Only (left: 10, right: 10), hintText: 'Please enter your phone number ', hintStyle: TextStyle(fontSize: 20, color: Colors.black12)), )Copy the code

AppBar

  • The title bar
_buildAppBar() {return AppBar(title: Text(' I am the title '), // Set the title actions: [CloseButton(), BackButton()],// Set some back buttons centerTitle: true, // Center the title toolbarHeight: kToolbarHeight,// Title bar height textTheme: TextTheme(), // Set the style); }Copy the code

RefreshIndicator

  • Refresh the component with child as ListView or CustomScrollView
_buildList() { return RefreshIndicator( child: ListView( children: [Text (' list 1), Text (' list 1), Text (' list 1), Text (' list 1), Text (' list 1)],), onRefresh: handRefresh); } Future<Null> handRefresh() async { await Future.delayed(Duration(microseconds: 1000)); return null; }Copy the code

PageView

  • The widget for rotation is similar to the ViewPage in Android
_buildPageView() {return Container(height: 100, margin: EdgeInsets. Only (top: 10)), PageView(//PageView must be set to a height, so it is wrapped in a Container. Children: [// Set each item Container(alignment: Align. Center,// Display margin: EdgeInsets. Only (left: 20, right: 20),// Set the left and right margins of item decorations: box decorations (color: Colors. GreenAccent, borderRadius: Borderradius.all (radius.circular (5))),// Set rounded corner child: Text('page1'), ), Container( alignment: Alignment.center, margin: EdgeInsets.only(left: 20, right: 20), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.all(Radius.circular(5))), child: Text('page2'), ), Container( alignment: Alignment.center, margin: EdgeInsets.only(left: 20, right: 20), decoration: BoxDecoration( color: Colors.lightGreen, borderRadius: BorderRadius.all(Radius.circular(5))), child: Text('page3'), ), ], ), ); }Copy the code

BottomNavigationBar

  • Bottom navigation bar
class HomePage extends State<HomePageState> { int _currentIndex = 0; @override Widget build(BuildContext context) {return Scaffold(appBar: _buildAppBar(),// Contains the status bar bottomNavigationBar: BottomNavigationBar(// BottomNavigationBar currentIndex: _currentIndex,// onTap: SetState (() {_currentIndex = index; }); }, items: [//items, at least 2 BottomNavigationBarItem(icon: icon (Icons. Home), label: 'home ', activeIcon: BottomNavigationBarItem(Icon: Icon(Icons. Home, color: colors.deeppurple,)), BottomNavigationBarItem(Icon: Icon(Icons. List)), 'list ', activeIcon: Icon(// select status Icons. List, color: colors.deeppurple,)),],), body: _currentIndex = = 0? _buildMain () : _buildList (), / / content floatingActionButton: _buildFloatingActionButton (), / / button); }}Copy the code

Scaffold

  • The container layout provides a list of widgets that help you quickly build a page. As you can see from the code above, there are ActionBar, bottom navigation, FloatActionBar, and so on for one-click components

MaterialApp

  • Generally used as an entry point to configure the overall App style, style, default properties and so on
void main() { runApp(MyFirstApp()); } class MyFirstApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Use materialApp', theme: ThemeData(// Here you can configure various properties of the entire App, such as theme color, text input field after the focus color, etc. PrimarySwatch: Colors. DeepPurple, / / set the theme color visualDensity: visualDensity. AdaptivePlatformDensity, / / set the unit), a home: HomePage (),); }}Copy the code

Flutter other widgets

ClipOval

  • ClipOval cuts its child widgets into circles

Opacity

  • Opacity Changes the Opacity of the child widget
_buildOpacityAndClipOval() {return Opacity(Opacity: 0.5,// Opacity child: ClipOval(child: Image.network( 'https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/96119b38be4be1dafc95fcbff0d9ee30~300x300.image', fit: BoxFit.cover, width: 60, height: 60, ), ), ); }Copy the code

ClipRRect and ClipRect

  • ClipRRect: Crop child widgets to rounded rectangles
  • ClipRect: Clipping child Widgets into rectangles
_buildClipRect() {return ClipRRect(borderRadius: borderradius.circular (5),// Set clipBehavior: Clip. AntiAlias,// antiAlias child: Image.network( 'https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/96119b38be4be1dafc95fcbff0d9ee30~300x300.image', fit: BoxFit.cover, width: 60, height: 60, ), ); }Copy the code

PhysicalModel

  • PhysicalModel is also responsible for trimming child widgets
_buildPhysicalModel() { return PhysicalModel( color: Colors.green, elevation: 5, borderRadius: BorderRadius. Circular (5), Child: Text(' hehehehehehe '),); }Copy the code

Center

  • Center the child widgets

Sizebox

  • Setting the width and height for the child widget is not useful if the child widget uses the width and height property
_buildCenter() {
  return SizedBox(
    width: 180,
    height: 180,
    child: Center(
      child: Image.network(
        'https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/96119b38be4be1dafc95fcbff0d9ee30~300x300.image',
        fit: BoxFit.cover,
        width: 60,
        height: 60,
      ),
    ),
  );
}
Copy the code

Padding

  • This is used to set margins for child widgets

FractionallySizedBox

  • The FractionallySizedBox allows child widgets to fill the screen horizontally or vertically
_buildFractionallySizedBox() { return FractionallySizedBox( widthFactor: 1, child: Container( alignment: Alignment. Center, color: Colors. Green, height: 50, child: Text (' ha ha ha ha ha ha),)); }Copy the code

The Stack and Positioned

  • Just like Framlayout in Android, the child widgets are layered over each other
  • The position of the toy widget in the Stack can be adjusted to show a special effect
_buildStack() { return Stack( children: [// Set the child widget group Image.network( 'https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/96119b38be4be1dafc95fcbff0d9ee30~300x300.image', fit: BoxFit. Cover, width: 80, height: 80,), offers a small glimpse of space. Image.network( 'https://sf1-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/wechat.ce329e6.png', fit: BoxFit.cover, width: 40, height: 40, )), ], ); }Copy the code

Wrap

  • It wraps automatically when there are multiple widgets
_buildWrap() { return Wrap( children: [ Container( margin: EdgeInsets.all(10), padding: EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(10)), child: Container(margin: EdgeInsets. All (10), padding: EdgeInsets. All (5), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(10)), child: Container(margin: EdgeInsets. All (10), padding: EdgeInsets. All (5), decoration: BoxDecoration(color: color.green, borderRadius: borderRadius. Circular (10)), child: Text(' it is my responsibility to protect people '),),],); }Copy the code

Expaned

  • Spread the child widgets in a horizontal or vertical direction, similar to the weight of Android widgets
// The nanded-type Column List<Widget> _buildexpnanded-type () {var List = <Widget>[]; List. The add (Text (" hello "); List. Add (Expanded(child: Container(decoration: BoxDecoration(color: color.green), child: Text(' I want to fill height '))); return list; }Copy the code

Some thoughts on Flutter layout

In fact, the beginning of contact with these widgets, somewhat conflict, compared to the existing Android writing interface components, a little too fragmented, there may be many ways to achieve a effect, the layout of the feel is determined by personal habits, and want to reconstruct some page layout, must not be quite laborious?…….. The current understanding is less so there will be such a simple problem, such as later understanding more perhaps do not contradict it…

It’s a great antidote to dyspraxia, for now…