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…