Flutter installation
Download and install Flutter Mac/Flutter Windows
Flutter Development wechat Project (II)
1.1 Brief introduction of wechat Discovery Page
- In the previous article “Flutter Development Practice: High Simulation of wechat (I) Home Page”, I explained the simple construction of the project framework. The whole APP is divided into four tabbars: wechat, Address book, Discover and ME. Among them, discovery is the simplest page. Start with the easiest page to build the discovery page home page.
1.2 APP framework optimization
1.2.1 Configuring the APP Logo and startup Image
- IOS Startup image configuration
- Android starts image configuration
1.2.2 Configuring the Resource Image
- The FLUTTER project resources are configured in pubspec.yaml
- How to use image resources in code:
- Images with different resolutions should be used in the same way as Android’s multi-image adaptation. Images with different resolutions can be placed in the corresponding directory as follows:
Use code:
new Image.asset("assets/images/a.png");
Copy the code
- Flutter loads resources into a project in two ways:
- Load by means of a rootBundle object (every Flutter application has a rootBundle object that can access the main asset bundle). If you are in a business scenario where you can’t get the context(not in the widget), use this, otherwise use the following method.
import 'package:flutter/services.dart'; Widget _createBody() { return new FutureBuilder( future: rootBundle.loadString('assets/a.json'), builder: (context,snapshot){ if(snapshot.hasData) { return new Text(snapshot.data.toString()); }});Copy the code
- Get the current BuildContext AssetBundle using DefaultAssetBundle. Recommended. It’s more flexible than method one. You can make your own.
import 'package:flutter/services.dart'; Widget _createBody() { return new FutureBuilder( future: DefaultAssetBundle.of(context).loadString('assets/a.json'), builder: (context,snapshot){ if(snapshot.hasData) { return new Text(snapshot.data.toString()); }});Copy the code
1.2.3 Configuring Other Resources
1.2.3.1 String Resource Configuration
Dart new.dart file, such as uidata.dart:
import 'package:flutter/material.dart'; Class UIData {//routes page path static const String homeRoute = "/home"; static const String profileOneRoute = "/View Profile"; static const String profileTwoRoute = "/Profile 2"; //strings static const String appName = "Flutter UIKit"; Static const String quickFont = "Quicksand"; static const String ralewayFont = "Raleway"; static const String quickBoldFont = "Quicksand_Bold.otf"; static const String quickNormalFont = "Quicksand_Book.otf"; static const String quickLightFont = "Quicksand_Light.otf"; //images static const String imageDir = "assets/images"; static const String pkImage = "$imageDir/pk.jpg"; Static const String enter_code_label = "Phone Number"; static const String enter_code_hint = "10 Digit Phone Number"; //gneric generic text static const String error = "error "; static const String success = "Success"; static const MaterialColor ui_kit_color = Colors.grey; //colors static List<Color> kitGradients = [// new color.fromrgbo (103, 218, 255, 1.0), // new color.fromrgbo (3, 169, 2), 244, 1.0), / / the new Color. FromRGBO (0, 122, 193, 1.0), Colors. BlueGrey. Shade800, Colors. Black87,]; static List<Color> kitGradients2 = [ Colors.cyan.shade600, Colors.blue.shade900 ]; //randomcolor static final Random _random = new Random(); /// Returns a random color. static Color next() { return new Color(0xFF000000 + _random.nextInt(0x00FFFFFF)); }}Copy the code
1.2.3.2 internationalization
See the official Internationalization tutorial for details
1.2.4 Adding a Dependency
Note that you need to go to Android Project Gradle to add dependencies only if you want to add dependencies for the platform.
1.2.5 Create four Home pages corresponding to four TabBars
knowledge
2.1 flutter layout
2.1.1 Row Layout
- Introduction to the
The Flex horizontal layout control, which can arrange child controls horizontally, is based on the Layout pattern of the Web’s Flexbox. Row child controls come in flexible and inflexible forms. Row first lists the inflexible child controls, subtracts their total width, and calculates how much free space there is. Row then lists the Flexible child controls in the available space in proportions determined by the flexibility.flex property. To control flexible child controls, use Expanded controls. Note that this control does not support sliding. If the child control exceeds the free space, an error will be reported. If you want to support horizontal sliding, consider using ListView. If you have only one child control, you can define the location of that child control using the Align or Center control.
- The instance
1 new Row(
2 children: <Widget>[
3 new Expanded(
4 child: new Text('Deliver features faster', textAlign: TextAlign.center),
5 ),
6 new Expanded(
7 child: new Text('Craft beautiful UIs', textAlign: TextAlign.center),
8 ),
9 new Expanded(
10 child: new FittedBox(
11 fit: BoxFit.contain, // otherwise the logo will be tiny
12 child: const FlutterLogo(),
13 ),
14 ),
15 ],
16 )
Copy the code
- usage
2.1.2 Column Vertical Layout
- Introduction to the Flex Vertical layout control, which enables you to arrange child controls vertically. The usage is the same as the Row control.
- The instance
new Column( 2 crossAxisAlignment: CrossAxisAlignment.start, 3 mainAxisSize: MainAxisSize.min, 4 children: <Widget>[ 5 new Text('We move under cover and we move as one'), 6 new Text('Through the night, we have one shot to live another day'), 7 new Text('We cannot let a stray gunshot give us away'), 8 new Text('We will fight up close, seize the moment and stay in it'), 9 New Text('It's either that or meet the business end of a bayonet'), 10 New Text('The code word is 'Rochambeau, 'dig me?'), 11 New Text('Rochambeau!', style: Defaulttextstyle.of (context).style.apply(fontSizeFactor: 2.0)), 12], 13)Copy the code
- usage
2.2 Basic Components of FLUTTER
The Flutter control itself usually consists of many small, single-purpose controls that combine to produce powerful effects. For example, Container is a commonly used control that consists of several controls responsible for layout, painting, positioning, and resizing. Specifically, Container is made up of LimitedBox, ConstrainedBox, Align, Padding, DecoratedBox, and Transform controls. Instead of subclassing Container to create a custom effect, You can combine these and other simple controls in this novel way.
The hierarchy of classes is flat to maximize the number of possible combinations.
When writing applications, you often use statelessWidgets and StatefulWidgets to write new controls. The difference between the two is whether you want to manage the state of the control. The primary task of a control is to implement the build function, which defines other lower-level controls within the control. The build function builds these controls in turn until the underlying render object.
- Compare the Flutter control with Android and IOS native controls
2.2.1 the Container
- Introduction to the
Container, a common control, consists of basic draw, position, and size controls. The visual elements responsible for creating the rectangle can be styled using boxDecorations, such as backgrounds, borders and shadows. Containers also have margins, fills and size limits, and can be transformed in three dimensions using matrices. No container of child controls is as large as possible, unless the incoming size constraint is infinite, in which case they are as small as possible. Containers with child controls give their dimensions to their children. We can control size through width, height, and constraints properties.
- The instance
new Container( constraints: new BoxConstraints.expand( height: Theme of (context). TextTheme. Display1. FontSize * 1.1 + 200.0), the padding: const EdgeInsets. All (8.0), color: Colors.teal.shade700, alignment: Alignment.center, child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white)), foregroundDecoration: new BoxDecoration( image: new DecorationImage( image: new NetworkImage('https://www.example.com/images/frame.png'), centerSlice: New Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),), transform: new Matrix4.rotationz (0.1),)Copy the code
2.2.2 Image
- Introduction to the
A control that displays an Image. The Image control has a variety of constructors: New Image, used to get the Image from the ImageProvider. New image. asset, used to fetch images from the AssetBundle using key. New Image.network, used to fetch images from URLS. New image.file, used to get images from file.
To automatically perform pixel density-aware resource resolution and specify images with AssetImage, you need to ensure that MaterialApp, WidgetsApp, and MediaQuery controls exist above the picture controls in the control tree.
Different phones have different pixel ratios, so you need to load different images according to the pixel ratios of the phone. It is very simple, just create 2.0x/… And 3.0 x /… Will do.
We specify the local image path in the file pubspec.yaml
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
Copy the code
Then the Text
The following example has seven different styles of text controls:
1 import 'package:flutter/material.dart'; 2 class TextDemo extends StatelessWidget { 3 @override 4 Widget build(BuildContext context) { 5 return new Scaffold( 6 AppBar: new appBar (7 title: new Text(' Text control '), 8), 9 Body: new Column(10 children: <Widget>[11 new Text(12 'red + black +25 ', 13 style: new TextStyle(14 color: const color (0xffff0000), 15 decoration: TextDecoration.lineThrough, 16 decorationColor: const Color(0xff000000), 17 fontSize: 25.0, 18), 19), 20 new Text(21 'orange + underline +24 ', 22 style: new TextStyle(23 color: const Color(0xffff9900), 24 decoration: TextDecoration.underline, 25 fontSize: 24.0, 26), 27), 28 New Text(29 'dotted +23 + gradient ', 30 style: New TextStyle(31 decoration: TextDecoration overline, 32 decorationStyle: TextDecorationStyle dashed, 33 fontSize: 23.0, 34 fontStyle: Italic, 35), 36), 37 new Text(38 'serif font +24 ', 39 style: new TextStyle(40 fontFamily: 'Serif ', 41 fontSize: 26.0, 42), 43), 44 New Text(45 'monospace font +24 + bold ', 46 style: new TextStyle(47 fontFamily: 'Monospace ', 48 fontWeight: 24.0, 49 fontWeight: fontweight. bold, 50), 51), 52 New Text(53' sky blue +25 +2 line span ', 54 style: New TextStyle(55 color: const color (0xff4a86E8), 56 fontSize: 25.0, 57 height: 2.0, 58), 59), 60 new Text(61 '24 +2 letterSpacing ', 62 style: new TextStyle(63 fontSize: 24.0, 64 letterSpacing: 2.0, 65), 66), 67] 68), 69); 70} 71} 72 void main() {73 runApp(74 new MaterialApp(75 title: 'New TextDemo() ', 76 home: new TextDemo(), 77), 78); 79}Copy the code
Operation effect:
2.2.4 Icon
- Introduction to the
Icon controls, drawn according to the rules described in IconData, such as IconDatas predefined in Material. This control is not interactive. To implement interactive ICONS, consider using the IconButton in Material. This control must be used within a Directionality control, which is usually automatically introduced by WidgetsApp or MaterialApp. See: docs. Flutter. IO/flutter/wid…
-
The instance
-
usage
2.2.5 RaisedButton
- Introduction to the
Material Design style floating button, in the shape of square paper hovering on the interface, click will produce ink diffusion effect. Avoid using it in dialog and card controls. For general pop-up controls, flat buttons are recommended to reduce layout layering. See: docs. Flutter. IO/flutter/mat…
-
The instance
-
When used, implement the onPressed callback method, otherwise the button is disabled, a disabledColor style flat button is displayed by default, and changing the color of the button does not take effect at this point. Note that the parent of this control must be a Material control. If you only need to click to produce ink diffusion, but don’t want to use the button, consider using the InkWell control directly. If necessary, the button is stretched to fit the child control.
2.2.6 Scaffold
- Introduction to the
The Scaffold implements the basic Material Design layout structure. That is, the MaterialApp child is the Scaffold Widget. Various layout elements that are defined on a single interface like left bars, snack bars, and bottom sheets are supported in Scaffold.
Scaffolding has the following major properties:
-
AppBar: An appBar (ActionBar, Toolbar in Android) displayed at the top of the interface
-
Body: The main content Widget displayed in the current interface
-
FloatingActionButton: FAB defined in Material design, the main function button of the interface
-
PersistentFooterButtons: Buttons that are fixed to the bottom display, such as the CONFIRM and cancel buttons at the bottom of the dialog box
-
Drawer: sidebar control
-
BackgroundColor: content of background color, the default is used ThemeData. ScaffoldBackgroundColor values
-
BottomNavigationBar: The navigation bar displayed at the bottom of the page
-
ResizeToAvoidBottomPadding: Is similar to the Android: Android windowSoftInputMode = “adjustResize”, control interface content body whether or not to the bottom of the layout to avoid being covered, such as when the keyboard display, layout again to avoid being the keyboard cover. The default value is true.
When snackbar or Bottom sheet is displayed, the ScaffoldState object needs to be retrieved by calling scaffold. of with the current BuildContext parameter. Then use the ScaffoldState. ShowSnackBar and ScaffoldState. ShowBottomSheet function to display.
Pay special attention to the Scaffold. Of parameter BuildContext. If the Widget containing that BuildContext is the parent Widget of that Scaffold, ScaffoldState is returned with ScaffoldState. ScaffoldState is returned with ScaffoldState. ScaffoldState is returned with ScaffoldState. For example, if in the Scaffold build function it is ok to use the build BuildContext parameter:
1 @override 2 Widget build(BuildContext context) { 3 return new RaisedButton( 4 child: new Text('SHOW A SNACKBAR'), 5 onPressed: () { 6 Scaffold.of(context).showSnackBar(new SnackBar( 7 content: new Text('Hello! '), 8)); 9}, 10); 11}Copy the code
- If the Scaffold function returns a Scaffold object, the ScaffoldState object cannot be found using the build BuildContext parameter because the Scaffold object is a child of the Widget. That Scaffold provides a new BuildConext by using a Builder in the Scaffold:
@override 2 Widget build(BuildContext context) { 3 return new Scaffold( 4 appBar: new AppBar( 5 title: new Text('Demo') 6 ), 7 body: new Builder( 8 // Create an inner BuildContext so that the onPressed methods 9 // can refer to the Scaffold with Scaffold.of(). 10 builder: (BuildContext context) { 11 return new Center( 12 child: new RaisedButton( 13 child: new Text('SHOW A SNACKBAR'), 14 onPressed: () { 15 Scaffold.of(context).showSnackBar(new SnackBar( 16 content: new Text('Hello! '), 17)); 18}, 19), 20); 21}, 22), 23); 24}Copy the code
In addition, widgets in the Build function can be created separately and a new BuildContext can be introduced to capture that Scaffold.
2.2.7 Appbar
- Introduction to the
AppBar and SliverAppBar are Material Design App Bars, also known as toolbars in Android. For Design guidelines for toolbars, see Material Design’s Toolbars. AppBar and SliverAppBar both inherit the StatefulWidget class and represent Toobar. The difference is that AppBar is located at the top of the fixed app. The SliverAppBar can scroll with content.
Their main attributes are as follows:
-
Leading: a control displayed in front of the title, usually showing the application logo on the front page; It is usually displayed as a back button on other screens
-
Title: The main content of the Toolbar, usually displayed as the title text of the current interface
-
Actions: A list of widgets that represent menus displayed in the Toolbar. For commonly used menus, IconButton is usually used. PopupMenuButton is usually used for menus that are not commonly used to display as three dots. After clicking, a secondary menu pops up
-
Bottom: An AppBarBottomWidget object, usually a TabBar. Use to display a Tab navigation bar under the Toolbar header
-
Elevation: The z-coordinate order of controls in ink and paper design. The default value is 4. For scrollable SliverAppBar, this value is 0 when the SliverAppBar is at the same level as the content, and when the content scroll SliverAppBar becomes Toolbar, Change the value of elevation
-
FlexibleSpace: A control displayed below the AppBar at the same height as the AppBar height to achieve special effects. This property is commonly used in SliverAppBar
-
BackgroundColor: The color of the APP bar. The default value is themedata.primarycolor. A change value is usually used with the following three attributes
-
Brightness: the brightness of the App bar, there are two themes, white and black. The default value for ThemeData primaryColorBrightness
-
IconTheme: App bar icon color, transparency, and size information. The default value is ThemeData primaryIconTheme
-
TextTheme: Text styles on the App bar. The default value is ThemeData primaryTextTheme
-
CenterTitle: Indicates whether the title is displayed in the center. The default value varies with the OPERATING system
- The instance
import 'package:flutter/material.dart'; 2 3 class AppBarBottomSample extends StatefulWidget { 4 @override 5 _AppBarBottomSampleState createState() => new _AppBarBottomSampleState(); 6 } 7 8 class _AppBarBottomSampleState extends State<AppBarBottomSample> with SingleTickerProviderStateMixin { 9 TabController _tabController; 10 11 @override 12 void initState() { 13 super.initState(); 14 _tabController = new TabController(vsync: this, length: choices.length); 15 } 16 17 @override 18 void dispose() { 19 _tabController.dispose(); 20 super.dispose(); 21 } 22 23 void _nextPage(int delta) { 24 final int newIndex = _tabController.index + delta; 25 if (newIndex < 0 || newIndex >= _tabController.length) 26 return; 27 _tabController.animateTo(newIndex); 28 } 29 30 @override 31 Widget build(BuildContext context) { 32 return new MaterialApp( 33 home: new Scaffold( 34 appBar: new AppBar( 35 title: const Text('AppBar Bottom Widget'), 36 leading: new IconButton( 37 tooltip: 'Previous choice', 38 icon: const Icon(Icons.arrow_back), 39 onPressed: () { _nextPage(-1); }, 40 ), 41 actions: <Widget>[ 42 new IconButton( 43 icon: const Icon(Icons.arrow_forward), 44 tooltip: 'Next choice', 45 onPressed: () { _nextPage(1); }, 46 ), 47 ], 48 bottom: new PreferredSize( 49 preferredSize: Const size.fromheight (48.0), 50 child: new Theme(51 data: Theme. Of (context). CopyWith (accentColor: Color.white), 52 child: new Container(53 height: 48.0, 54 alignment: align.center, 55 child: new TabPageSelector(controller: _tabController), 56 ), 57 ), 58 ), 59 ), 60 body: new TabBarView( 61 controller: _tabController, 62 children: choices.map((Choice choice) { 63 return new Padding( 64 padding: Const EdgeInsets. All (16.0), 65 child: New ChoiceCard(Choice: choice), 66); 67 }).toList(), 68 ), 69 ), 70 ); 71 } 72 } 73 74 class Choice { 75 const Choice({ this.title, this.icon }); 76 final String title; 77 final IconData icon; 78 } 79 80 const List<Choice> choices = const <Choice>[ 81 const Choice(title: 'CAR', icon: Icons.directions_car), 82 const Choice(title: 'BICYCLE', icon: Icons.directions_bike), 83 const Choice(title: 'BOAT', icon: Icons.directions_boat), 84 const Choice(title: 'BUS', icon: Icons.directions_bus), 85 const Choice(title: 'TRAIN', icon: Icons.directions_railway), 86 const Choice(title: 'WALK', icon: Icons.directions_walk), 87 ]; 88 89 class ChoiceCard extends StatelessWidget { 90 const ChoiceCard({ Key key, this.choice }) : super(key: key); 91 92 final Choice choice; 93 94 @override 95 Widget build(BuildContext context) { 96 final TextStyle textStyle = Theme.of(context).textTheme.display1; 97 return new Card( 98 color: Colors.white, 99 child: new Center( 100 child: new Column( 101 mainAxisSize: MainAxisSize.min, 102 crossAxisAlignment: CrossAxisAlignment.center, 103 children: <Widget>[104 new Icon(choice.icon, size: 128.0, color: textstyle.color), 105 new Text(choice.title, style: textStyle), 106 ], 107 ), 108 ), 109 ); 110 } 111 } 112 113 void main() { 114 runApp(new AppBarBottomSample()); 115}Copy the code
Operation effect:
2.2.8 FlutterLogo
- Describes how to define the logo of a flutter application. This control is bound by an IconTheme.
- The instance
import 'package:flutter/material.dart'; 2 3 void main() { 4 runApp(new FadeAppTest()); 5 } 6 7 class FadeAppTest extends StatelessWidget { 8 // This widget is the root of your application. 9 @override 10 Widget build(BuildContext context) { 11 return new MaterialApp( 12 title: 'Fade Demo', 13 theme: new ThemeData( 14 primarySwatch: Colors.blue, 15 ), 16 home: new MyFadeTest(title: 'Fade Demo'), 17 ); 18 } 19 } 20 21 class MyFadeTest extends StatefulWidget { 22 MyFadeTest({Key key, this.title}) : super(key: key); 23 final String title; 24 @override 25 _MyFadeTest createState() => new _MyFadeTest(); 26 } 27 28 class _MyFadeTest extends State<MyFadeTest> with TickerProviderStateMixin { 29 AnimationController controller; 30 CurvedAnimation curve; 31 32 @override 33 void initState() { 34 controller = new AnimationController(duration: const Duration(milliseconds: 2000), vsync: this); 35 curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn); 36 } 37 38 @override 39 Widget build(BuildContext context) { 40 return new Scaffold( 41 appBar: new AppBar( 42 title: new Text(widget.title), 43 ), 44 body: new Center( 45 child: new Container( 46 child: new FadeTransition( 47 opacity: Curve, 48 Child: new FlutterLogo(49 size: 100.0, 50)))), 51 floatingActionButton: new FloatingActionButton( 52 tooltip: 'Fade', 53 child: new Icon(Icons.brush), 54 onPressed: () { 55 controller.forward(); 56}, 57), 58); 59}} 60Copy the code
2.2.9 Placeholder
- Introduction to the
A placeholder control that draws a box indicating that additional controls will be added at that location in the future. This control is useful during development as a reminder that the interface is not yet complete. By default, the size of a control ADAPTS to its container. If the control is in unbounded space, it resizes itself based on the given fallbackWidth and fallbackHeight. See: docs. Flutter. IO/flutter/wid…
Further study of
3.1 Structural analysis of the FLUTTER project
- Pure Flutter project structure
- projectName
-android // Android project file -build // Project build output file -ios // Project ios project file -lib // Dart file in the project -src // Include other source files -main.dart // Automatically generated project entry file -assets -images -2.0x -3.0x XXXXX // Images can be placed directly in images-fonts // Pubspec. yaml // project dependency config file \
- Mix up the Flutter project
As shown in the picture above, let’s take a look at the differences between a Flutter hybrid project and our traditional Android project. There is no difference between the gradle file, which contains the gradle version of our current project. Next is our Android folder, which contains our Android project. Next is our Asset folder, which contains the resources of the Flutter project, including images. Font, video, and any other resource files, http_plugin, we will not look at it, because it is a plug-in project, we will look at the last, next to the ios folder, of course, where we store all the content of the ios project, next to the lib folder, The last and most important file is pubspec.yaml. This file is used to configure the dependencies required by the FLUTTER project, etc. Here we can see what is special about the flutter project as a whole. Of course, it is still only a whole, but let’s compare it with a picture, and take a look at the overall differences with traditional Android projects.
The last part of the Flutter project is the stuff of the Flutter project itself, including its resources and code, as well as dependencies, etc.
3.2 The flutter project pubspec.yaml file
The pubspecyaml file is used to configure the resource and library dependencies of FLUTTER
- The yamL syntax is case-sensitive and uses colons and indents to represent hierarchies, only Spaces, not TAB keys. There is no requirement for Spaces, and sibling alignment can represent three data types: constants, objects, and arrays
Url: http://www.wolfcode.cn # indicates the value of server.host. Server: host: http://www.wolfcode.cn # array 3.14 hasChild: true # Define a Boolean value name: 'Hello YAML' # defines a stringCopy the code
- Add the library dependencies under Dependencies:
X < dio: ^2.1.0 > dio: ^2.1.0Copy the code
- Add resource dependencies under FLUTTER
Flutter: user-material-design: true assets: -images /lake.jpg - images/light.jpgCopy the code
The colon must be followed by a space, and the – symbol for array elements must be followed by a space, otherwise the syntax fails. Images /lake.jpg is the path to the image. Create an images folder under Project and put lake.jpg in it.
3.3 Image Resource Configuration of the FLUTTER Project
A Flutter application can contain both code and assets (sometimes called resources). Asset is packaged into the program installation package and accessible at run time. Common types of assets include static data (such as JSON files), configuration files, ICONS, and images (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and WBMP).
flutter:
assets:
- assets/my_icon.png
- assets/background.png
Copy the code
- Asset variation (variant)
- Variation refers to the selection of resources for different scenarios during construction. Can be analogous to Android multi-image resource adaptation: automatically select XXH or XH under the image load.
- When you build a resource according to pubspec.yaml, any files with the same name are found in adjacent directories, and they are put into the package together.
The application contains the following files: Assets /image/a.png assets/image/2x/a.png assets/image/3x/a.png pubspec.yaml Configuration: flutter: assets: - Assets /calendar. PNG Then, all three types of A.png will be added to the asset bundle. The last two are considered variants.Copy the code
- Load resources
Since the | the original address