Flutter development learning.md

Flutter development learning.md

2020.03.02

Follow the video tutorials and documents to learn

Component

  • Widget, Parts,Center , ,Text MaterialApp Scaffold

Text component

The widget allows you to create a formatted text.

class HomeContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
   //TODO: implement build
    return Center(
      child: Container(
        child: Text(
          ' , ',
          textAlign: TextAlign.left,
          overflow: TextOverflow.ellipsis,
          maxLines: 2,//
         //textDirection: TextDirection.rtl,//
         //textScaleFactor: 1.0,//
          style:TextStyle(//
            fontSize: 30.0,
            fontWeight: FontWeight.w800,
            color: Colors.blue,
            decoration: TextDecoration.lineThrough,
            decorationColor: Colors.white,
            decorationStyle: TextDecorationStyle.dashed,//
            wordSpacing: 3.0,
            letterSpacing: 1.5,
            fontStyle: FontStyle.italic
          ),
        ),
        width:300.0,
        height: 300.0,
        decoration: BoxDecoration(//
          color: Colors.yellow,
          border: Border.all(
            color: Colors.red,
            width: 2.0,
          ),
          borderRadius: BorderRadius.all(
           //Radius.circular(150)//
            Radius.circular(8.0)
          ),
         //borderRadius: BorderRadius.circular(20) 
        ),
       //margin: EdgeInsets.all(20),//
        padding: EdgeInsets.all(20),
       //padding: EdgeInsets.fromLTRB(10, 20, 40, 5),
       //transform: Matrix4.translationValues(100, 30, 0),
       //transform: Matrix4.rotationZ(0.3),
       //transform:Matrix4.diagonal3Values(1.2, 1, 1),
        alignment: Alignment.center,//

      ),
    );
  }
  
}
 

Container component

The container component is equivalent to the divlayout component. Rectangular visual elements can be created.

MaterialApp component

Scaffold components

Picture component

Introduce remote picturesImage.network

Ordinary introduction picture

child: Image.network(
    'https://user-gold-cdn.xitu.io/2020/3/2/1709a01b029a6ef0?w=344&h=682&f=png&s=26519',
    alignment: Alignment.topLeft, 
   //color: Colors.blue,
   //colorBlendMode: BlendMode.darken, 
    fit: BoxFit.contain,
    repeat: ImageRepeat.noRepeat,
    width: 200,
    height: 200,
),
 

Achieve rounded corners and round pictures:

decoration: BoxDecoration( 
    color: Colors.yellow,
    borderRadius: BorderRadius.circular(150),
    image: DecorationImage(
        image: NetworkImage('https://user-gold-cdn.xitu.io/2020/3/2/1709a01b029a6ef0?w=344&h=682&f=png&s=26519'),
    fit: BoxFit.cover
    )
),
 

Recommended to use this one

child: ClipOval(
    child: Image.network(
        'https://user-gold-cdn.xitu.io/2020/3/2/1709a01b029a6ef0?w=344&h=682&f=png&s=26519',
        width:100.0,
        height: 100.0,
        fit: BoxFit.cover,
    ),
),
 

Introduce local picturesImage.asset

  1. Added images folder: imagesincluded in the folder 2.0x( ) 3.0x( ) 4.0x , as shown below:

  1. Open pubspec.yamlstatement about the image files added attention to configuration, as shown below:

  1. Use in code
child: Container(
    child: Image.asset( 
        'images/2.png' ,
        fit:BoxFit.cover
    ),
 

2020.03.03

Icon component

Material icons

new IconButton(
    icon: new Icon(Icons.menu),
    tooltip: 'Navigation menu',
    onPressed: null,//null   button
),
 

ListView list component

ListView list parameters

name Types of Description
scrollDirection Axis Axis.horizontal horizontal column, Axis.vertical vertical list
padding EdgeInsetsGeometry Padding
resolve bool Reverse order of components
children List List element
  • ListView
  • ListView.builder

Default vertical list (graphic list)

Horizontal list

scrollDirection:Axis.horizontal

Matrix list

news list:

class HomeContent extends StatelessWidget{
   //   _   
   //2. listData map 
    List<Widget> _getData(){
  
          var tempList = listData.map((v){//map (xx,xx)
            return ListTile(
              leading: Image.network(v['imageUrl']),
              title: Text(v['title']),
              subtitle: Text(v['author']),
              trailing:Icon(Icons.arrow_forward_ios,color:Colors.red), 
            );
          });
    
          return tempList.toList();
    }
    
     @override
      Widget build(BuildContext context) {
       //
          return ListView(
              children: this._getData(),//
          );
          
      }
      
}
 

Dynamic list

import './res/listData.dart';

class HomeContent extends StatelessWidget{
   //
      Widget _getListData(context,index){
        return ListTile(
          leading: Image.network(listData[index]['imageUrl']),
          title: Text(listData[index]['title']),
          subtitle: Text(listData[index]['author']),
          trailing:Icon(Icons.arrow_forward_ios,color:Colors.orange), 
        );
      }
      
      @override
      Widget build(BuildContext context) {
       //TODO: implement build
        return ListView.builder(
           itemCount: listData.length,
           itemBuilder: this._getListData,//
        );
          
      }

}
 

ListTile component

this.leading,
this.title,
this.subtitle,
this.trailing,
 

CircleAvatar component

Avatar component

 ListTile(
   //leading: Image.network('https://www.itying.com/images/flutter/2.png',fit: BoxFit.cover,),
    leading:CircleAvatar(
      backgroundImage:NetworkImage(value['imageUrl'])
    ),

    title: Text(value['title']),
    subtitle: Text(value['description'],maxLines: 2,overflow:TextOverflow.ellipsis),
  ),
 

GridView component to achieve grid layout

name Types of Description
scrollDirection Axis Rolling method
padding EdgeInsetsGeometry Padding
resolve bool Reverse order of components
crossAxisSpacing double Spacing between horizontal sub-widgets
mainAxisSpacing double Spacing between vertical sub-widgets
crossAxisCount int Number of widgets in a row
childAspectRatio double The ratio of the width to the height of the child widget
children []
gridDelegate SliverGridDelegateWithFixedCrossAxisCount (commonly used), SliverGridDelegateWithMax Control layout is mainly used in GridView.builder

GridView.count

Static list

class LayoutDemo extends StatelessWidget {  


  List<Widget> _getListData() {
      var tempList=listData.map((value){
          return Container(            
            child:Column(
                children: <Widget>[
                  Image.network(value['imageUrl']),
                  SizedBox(height: 12),
                  Text(
                    value['title'],
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      fontSize: 20
                    ),
                  )
                ],
            ),
            decoration: BoxDecoration(
              border: Border.all(
                color:Color.fromRGBO(233, 233,233, 0.9),
                width: 1
              )
            ),
           //height: 400, //
          );
      });
     //('xxx','xxx')
      return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {    
    return GridView.count(
        crossAxisSpacing:10.0 ,  // Widget  
        mainAxisSpacing: 10.0,   // Widget  
        padding: EdgeInsets.all(10),
        crossAxisCount: 2, // Widget  
       //childAspectRatio:0.7, //
        children: this._getListData(),
    );
  }
}
 

GridView.builder

Dynamic list

class LayoutDemo extends StatelessWidget {  
  Widget _getListData (context,index) {
        return Container(            
            child:Column(
                children: <Widget>[
                  Image.network(listData[index]['imageUrl']),
                  SizedBox(height: 12),
                  Text(
                    listData[index]['title'],
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      fontSize: 20
                    ),
                  )
                ],
            ),
            decoration: BoxDecoration(
              border: Border.all(
                color:Color.fromRGBO(233, 233,233, 0.9),
                width: 1
              )
            ),
              
           //height: 400, //
          );
  }

  @override
  Widget build(BuildContext context) {    
    return GridView.builder(
       //
        gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisSpacing:10.0 ,  // Widget  
          mainAxisSpacing: 10.0,   // Widget            
          crossAxisCount: 2, // Widget  
        ),
        itemCount: listData.length,
        itemBuilder:this._getListData,
    );
  }
}

 

Padding() component

When some elements are not paddingavailable, they can be wrapped in a layer Padding() .

There are two parameters padding: EdgeInsets.fromLTRB(left, top, right, bottom),, child: nullshall write.

Attributes Description
padding padding value, EdgeInsetss sets the padding value
child Subassembly
Widget build(BuildContext context) {
    return Padding(
      padding:EdgeInsets.fromLTRB(0, 0, 10, 0),
      child: GridView.count(
        crossAxisCount: 2,//
        childAspectRatio: 1.5,//
        children: <Widget>[
            Padding(
              padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
              child:  Image.network('https://www.itying.com/images/flutter/1.png',fit: BoxFit.cover),
            ),
             Padding(
              padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
              child:  Image.network('https://www.itying.com/images/flutter/2.png',fit: BoxFit.cover),
            ),
             Padding(
              padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
              child:  Image.network('https://www.itying.com/images/flutter/3.png',fit: BoxFit.cover),
            )
        ],
      ),

    );
}
 

Row horizontal layout component

Row

Attributes Description
mainAxisAlignment Spindle sorting method
crossAxisAlignment How to sort the secondary axis
children Component sub-element
return Row(//flex  
    crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
        Expanded(child: Text('Row   1',textAlign: TextAlign.center,)),
        Expanded(child: Text('Row   2',textAlign: TextAlign.center,)),
        Expanded(child: FittedBox(
          fit:BoxFit.contain,
          child:const FlutterLogo(),
        ))
    ],
);
 

Column vertical layout component

Column

Attributes Description
mainAxisAlignment The sorting method of the main axis (MainAxisAlignment.spaceEvenly, MainAxisAlignment.center)
crossAxisAlignment How to sort the secondary axis
children Component sub-element
return Container( height: 700,
    width: 500,
    color: Colors.black26, 
    child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
        children: <Widget>[
            IconContainer(Icons.home,color:Colors.red), IconContainer(Icons.search,color:Colors.blue), IconContainer(Icons.send,color:Colors.orange),
        ],
    ),
)
 

Expanded is similar to the Flex layout in the Web

Attributes Description
flex The ratio of the entire parent Row/Column of the element station
child Child element

Spacing SizedBox(height:10,width)

2020.03.04

Stack stacking components

Attributes Description
alignment Configure the display position of all child elements alignment: Alignment.center,
children Subassembly
Widget build(BuildContext context) {
    return Stack( 
        alignment: Alignment.center,
       //alignment: Alignment.topCenter,
       //alignment: Alignment(0,1),//x,y  BottomCenter
        children: <Widget>[//Stack children 
          Container(
            width:200,
            height:300,
            color:Colors.red,
          ),
          Text(
            ' ',
            style: TextStyle(
              fontSize:30,
              color: Colors.white
            ),
          ),
          
        ],
    );
  }
 

When a plurality of components needs to be positioned, may be used Stackin combination Alignor Positionedachieve positioning layout.

Align component

StackBinding assembly Aligncomponents may control the display position of each sub-element

Attributes Description
alignment Configure the display position of all child elements alignment: Alignment.center
children Subassembly

Positioned components

StackBinding assembly Positionedcomponents may also control the display position of each sub-element

Attributes Description
top The distance from the top of the child element
bottom The distance of the child element from the bottom
left The distance of the child element from the left
right The distance from the child element to the right
child Subassembly
 Widget build(BuildContext context) {
    return Center(
      child:Container(
        width:300,
        height:400,
        color:Colors.red,
        child: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.center,
              child: Icon(Icons.home,color:Colors.white),
            ),
            Align(
              alignment: Alignment(0.5,0.5),
              child: Icon(Icons.search,color:Colors.white),
            ),
            Positioned(
              top: 20,
              left: 20,
              child:  Icon(Icons.save,color:Colors.white)
            )

          ],
        ),
       ),
    );
}
 

AspectRatio, Card card components

AspectRatio component, set the aspect ratio of the picture

Attributes Description
aspectRatio Aspect ratio (20/9)
children Subassembly

Card card components

Attributes Description
margin EdgeInsets.all(20)
children Subassembly
Shape The shadow effect of Card. The default shadow effect is a rectangle with rounded corners.
class HomeContent extends StatelessWidget {
  
  List<Widget> _getData(){
    var tempList = listData.map((value){
        return Card(
          margin: EdgeInsets.all(20),
          child: Column(
            children: <Widget>[
              AspectRatio(
                aspectRatio: 20/9,//
                child: Image.network(value['imageUrl'],fit: BoxFit.cover,),
              ),
              ListTile(
               //leading: Image.network('https://www.itying.com/images/flutter/2.png',fit: BoxFit.cover,),
                leading:CircleAvatar(
                  backgroundImage:NetworkImage(value['imageUrl'])
                ),

                title: Text(value['title']),
                subtitle: Text(value['description'],maxLines: 2,overflow:TextOverflow.ellipsis),
              ),
            ],
            
          ),
        );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: this._getData(),  
    
    );
  }
}
 

RaisedButton defines a button

class MyButton extends StatelessWidget {
  final String text;
  const MyButton(this.text,{Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
   //TODO: implement build
    return RaisedButton(
      child: Text(this.text),
      textColor:Theme.of(context).accentColor,
      color:Colors.red,
      onPressed: (){}
    );
  }
}

 

The wrap component realizes flow layout, automatic line wrapping

Attributes Description application
direction The direction of the main axis, horizontal by default direction:Axis.vertical/Axis.horizontal
alignment Spindle alignment alignment:WrapAlignment.start
spacing Spacing in the direction of the main axis spacing:10
runAlignment run . run can be understood as a new row or column, if it is laid out in the horizontal direction, run can be understood as a new row runAlignment: WrapAlignment.spaceAround
runSpacing run spacing runSpacing:10
textDirection Text direction
verticalDirection Defines the order of children placement, the default is down, see the introduction of Flex related properties.

StateLessWidget stateless component

StatefulWidget stateful component

  • StatelessWidget is a stateless component, a widget whose state is immutable;
  • StatefulWidget is a stateful component, and the state it holds may change during the widget's life cycle. In layman's terms: If we want to change the data in the page, we need to use StatefulWidget at this time

Bind data on the page, change page data

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  int count = 1;
  List list = new List();

  get textDirection => null;

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
         RaisedButton(
          child: Text(' '),
          onPressed: (){
            setState(() {
              this.list.add(' ${this.count++}');
            });
          }
        ),
        RaisedButton(
          child: Text(' '),
          onPressed: (){
            setState(() {
              this.list.clear();
              this.count = 1;
            });
          }
        ),
        SizedBox(
          height:20,
        ),
        Column(
          children:this.list.map((value){
            return  Padding(padding: EdgeInsets.all(10),
              child:Text(value,style: TextStyle(fontSize: 20))
            );
          }).toList(),
        ), 
      ],
    );
  }
}
 

2020.03.05

BottomNavigationBar component

BottomNavigationBar is the bottom navigation bar, which allows us to define the bottom Tab switch, bottomNavigationBar is the parameter of the Scaffold component.

Attributes Description
items List<BottomNavigationBarItem> Bottom navigation bar button collection
iconSize icon size
currentIndex Which one is selected by default
fixedColor Selected color
type BottomNavigationBarType.fixed BottomNavigationBarType.shifting
onTap Selected change callback function

The bottom navigation will involve page switching, so you need to extract the code, as shown in the figure below: Tabs.dartset in.


import 'package:flutter/material.dart';
import './tabs/HomePage.dart';
import './tabs/CategoryPage.dart';
import './tabs/SettingsPage.dart';

class HomeTabs extends StatefulWidget {
  HomeTabs({Key key}) : super(key: key);

  @override
  _HomeTabsState createState() => _HomeTabsState();
}

class _HomeTabsState extends State<HomeTabs> {

  int _currentIndex = 0;
  List _pageList=[
    HomePage(),
    CategoryPage(),
    SettingsPage()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Fultter demo')),
        body: this._pageList[this._currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: this._currentIndex,    //
          iconSize: 30.0,                      //icon 
          fixedColor: Colors.red,              //
          type: BottomNavigationBarType.fixed, //shifting   fixed
          onTap:(int index){                   //state 
            setState(() {
              this._currentIndex = index;
            });
          },
          items: [                             //        
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text(' ')
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.category),
              title: Text(' ')
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text(' ')
            )
          ]
        ),
      );
  }
}
 

2020.03.06

routing

Ordinary routingNavigator.push Navigator.pop

  1. Jump
  2. Jump to pass by value
 Center(
  child: RaisedButton(
    child: Text(' '),
    onPressed: (){
      Navigator.of(context).push(
        MaterialPageRoute(
           builder: (context)=>SearchPage(title:' ')//
        ) 
      );
    },
    color: Theme.of(context).accentColor, 
    textTheme: ButtonTextTheme.primary
  ),
)
 

Named routeNavigator.pushNamed(context, '/form');

1. MaterialAppConfigure routes in, jumpNavigator.pushNamed(context, '/form');

return MaterialApp(
    home: HomeTabs(),
    routes: {
        '/search':(context)=>SearchPage(),
        '/form':(context)=>FormPage(),
    },
    theme: ThemeData(primarySwatch: Colors.yellow),
);

RaisedButton(
    child: Text('/'),
    onPressed: (){
      Navigator.pushNamed(context, '/form');
    },
    color: Theme.of(context).accentColor, 
    textTheme: ButtonTextTheme.primary
),
 

2. Extract the routing configuration and pass the value

(1) New Routes.dartfile

import 'package:flutter/material.dart';

import '../pages/Search.dart';
import '../pages/Form.dart';

//
final routes={
      '/search':(context)=>SearchPage(),
      '/form':(context,{arguments})=>FormPage(arguments:arguments),
};

//
var onGenerateRoute=(RouteSettings settings) {
     // 
      final String name = settings.name; 
      final Function pageContentBuilder = routes[name];
      if (pageContentBuilder != null) {
        if (settings.arguments != null) {
          final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context, arguments: settings.arguments));
          return route;
        }else{
            final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context));
            return route;
        }
      }
};
 

(2) main.dartIntroduce

import 'package:flutter/material.dart';
import './pages/Tabs.dart';

import './routes/Routes.dart';

void main() => runApp(MyApp());

//
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeTabs(),
      initialRoute: '/',    //
      onGenerateRoute:onGenerateRoute,//
      theme: ThemeData(primarySwatch: Colors.yellow),
    );
  }
}
 

(3) Home.dartReference by value

RaisedButton(
    child: Text('/'),
    onPressed: (){
      Navigator.pushNamed(context, '/form',arguments:{
        'id':1212
      });
    },
    color: Theme.of(context).accentColor, 
    textTheme: ButtonTextTheme.primary
),
 

(4) From.dartReceive value transfer

StatelessWidgetReceived value in stateless component:

class FormPage extends StatelessWidget {

   final arguments;
   FormPage({this.arguments});//

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(' ')),
      body:Container(
        child:  Text(" ${arguments != null ? arguments['id'] : '0'}"),
      )
    );
  }
}
 
StatefulWidgetReceive values in stateful components:
class FormPage extends StatefulWidget {

  final arguments;
  FormPage({this.arguments});//

  @override
  _FormPageState createState() => _FormPageState(this.arguments);
}

class _FormPageState extends State<FormPage> {

  var arguments;

  _FormPageState(arguments){
    this.arguments = arguments;
  }//

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(' ')),
      body:Container(
        child: Text(" ${arguments != null ? arguments['id'] : '0'}"),
      )
    );
  }
}
 

Return to the previous page

 Navigator.of(context).pop();
 

Next step

 Navigator.pushNamed(context, '/registerSecond');
 

Route replacement

Navigator.of(context).pushReplacementNamed('/registerSecond');
 

Return to root route

Navigator.of(context).pushAndRemoveUntil(
  new MaterialPageRoute(builder: (context) => new Tabs()),                  
   (route) => route == null
);
 

Specify which root route to return:

Navigator.of(context).pushAndRemoveUntil(
  new MaterialPageRoute(builder: (context) => new Tabs(index:1)),                  
   (route) => route == null
);
 
Tabs.dartReceive index parameters:
import 'package:flutter/material.dart';
import './tabs/HomePage.dart';
import './tabs/CategoryPage.dart';
import './tabs/SettingsPage.dart';

class Tabs extends StatefulWidget {

  final index ;
  
  Tabs({this.index = 0 });

  @override
  _TabsState createState() => _TabsState(this.index);
}

class _TabsState extends State<Tabs> {


  int _currentIndex;
  List _pageList=[
    HomePage(),
    CategoryPage(),
    SettingsPage()
  ];
 
  _TabsState(index){
    this._currentIndex = index;
  }

  List _titleList=[
    ' ',' ',' '
  ];
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text(this._titleList[this._currentIndex])),
        body: this._pageList[this._currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: this._currentIndex,    //
          iconSize: 30.0,                      //icon 
          fixedColor: Colors.red,              //
          type: BottomNavigationBarType.fixed, //shifting   fixed
          onTap:(int index){                   //state 
            setState(() {
              this._currentIndex = index;
            });
          },
          items: [                             //        
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text(' ')
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.category),
              title: Text(' ')
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text(' ')
            )
          ]
        ),
      );
  }
}
 

AppBar component

Custom top style

Attributes description
leading A control displayed in front of the title, the logo of the application is usually displayed on the home page; it is usually displayed as a return button on other interfaces
title Title, usually displayed as the title text of the current interface, you can put components
actions Usually use IconButton to indicate that you can put a button group
bottom Usually put tabBar, a Tab navigation bar is displayed below the title
backgroundColor Navigation background color
iconTheme Icon style
textTheme Text style
centerTitle Whether the title is displayed in the center
Widget build(BuildContext context) {
    return Scaffold(
      appBar:AppBar(
        title: Text('AppBarPage',style:TextStyle(color:Colors.white)),
        backgroundColor: Colors.blue,
       //leading: Icon(Icons.menu,color: Colors.white),
        leading: IconButton(//   logo; 
            icon: Icon(Icons.menu,color: Colors.white), 
            onPressed: (){
              print('menu');
            }
        ),
        actions: <Widget>[//
           IconButton(
              icon: Icon(Icons.search,color: Colors.white), 
              onPressed: (){
                print('search');
              }
           ),
            IconButton(
              icon: Icon(Icons.settings,color: Colors.white), 
              onPressed: (){
                print('settings');
              }
           ),
        ],
        centerTitle:true,//
      ),
      body: Container(
       child: Text('appbar'),
      ),
    );
  }
 

Custom TabBar to achieve top Tab switching

TabBar common attributes:

Attributes description
tabs The displayed label content, generally using Tab objects, can also be other Widgets
controller TabController object
isScrollable Whether it is scrollable
indicatorColor Indicator color
indicatorWeight Indicator height
indicatorPadding Padding of the bottom indicator
indicator Indicator decoration, such as borders, etc.
indicatorSize The indicator size calculation method, TabBarIndicatorSize.label is the same width as the text, and TabBarIndicatorSize.tab is the same width as each tab
labelColor Select the label color
labelStyle Select the style of label
labelPadding Padding value of each label
unselectedLabelColor Label color not selected
unselectedLabelStyle Style of label not selected
class _AppBarPageState extends State<AppBarPage> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,//
      child: Scaffold(
        appBar:AppBar(
          title: Text('AppBarPage',style:TextStyle(color:Colors.white)),
          backgroundColor: Colors.blue,
         //leading: Icon(Icons.menu,color: Colors.white),
          leading: IconButton(//   logo; 
              icon: Icon(Icons.menu,color: Colors.white), 
              onPressed: (){
                print('menu');
              }
          ),
         //actions: <Widget>[//
         //  IconButton(
         //      icon: Icon(Icons.search,color: Colors.white), 
         //      onPressed: (){
         //        print('search');
         //      }
         //  ),
         //    IconButton(
         //      icon: Icon(Icons.settings,color: Colors.white), 
         //      onPressed: (){
         //        print('settings');
         //      }
         //  ),
         //],
          centerTitle:true,//
          bottom: TabBar(
            indicatorColor:Colors.orange,
            labelColor:Colors.white,
            indicatorSize:TabBarIndicatorSize.label,
            tabs: <Widget>[
              Tab(text:' '),
              Tab(text:' '),
            ],
          ),
        ),
        body: TabBarView(children: <Widget>[
            ListView(children: <Widget>[
              ListTile(
                title:Text(' tab')
              ),
              ListTile(
                title:Text(' tab')
              ),
              ListTile(
                title:Text(' tab')
              ),

            ],
           ),
            ListView(children: <Widget>[
                ListTile(
                  title:Text(' tab')
                ),
                ListTile(
                  title:Text(' tab')
                ),
                ListTile(
                  title:Text(' tab')
                ),
              ],
           ),
          ]
        ),
      ),
    );
  }
}
 

TabBar at the top of the navigation

  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 4, 
      child:Scaffold(
        appBar:AppBar(
          title: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                flex:1,
                child: TabBar(// ategoryPage Scaffold title bottom 
                indicatorColor:Colors.red,
               //labelColor:Colors.white,
                indicatorSize:TabBarIndicatorSize.label,
                tabs: <Widget>[
                  Tab(text:' '),
                  Tab(text:' '),
                  Tab(text:' '),
                  Tab(text:' '),
                ],
              )
            )
          ]),
        ),
        body: TabBarView(children: <Widget>[])
    )
}
 

TabController implements Tabs switching

Another way to customize TabBar in AppBar to implement Tabs.

import 'package:flutter/material.dart';

class TabBarControllerPage extends StatefulWidget {
  TabBarControllerPage({Key key}) : super(key: key);

  @override
  _TabBarControllerPageState createState() => _TabBarControllerPageState();
}

//1   with SingleTickerProviderStateMixin
class _TabBarControllerPageState extends State<TabBarControllerPage> with SingleTickerProviderStateMixin{

 //2  _tabController
  TabController _tabController;

 //3  
  @override
  void initState(){//
    super.initState();
    _tabController = new TabController(vsync: this,length: 2);

    _tabController.addListener((){//6  tab 
      print(_tabController.index);
    });
  }

   @override
   void dispose(){//
     super.dispose();
     _tabController.dispose();//
   }
   
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar:AppBar(
        title:Text('TabBarController'),
        bottom: TabBar(
          controller: this._tabController,//4  TabBar controller
          tabs: <Widget>[
            Tab(text:' '),
            Tab(text:' ')
          ],
        ),
      ),
      body:TabBarView(
        controller: this._tabController,//5  TabBarView controller
        children: <Widget>[
          Center(child:Text(' ')),
          Center(child:Text(' ')),
        ],
      )
    );
  }
}

 

Drawer drawer component

Drawer sidebar

return Scaffold(
    appBar: AppBar(
        title: Text("Flutter App"), ),
    drawer: Drawer(
        child: Text(' '),
    ),
    endDrawer: Drawer(
        child: Text(' '), 
    ),
);
 

DrawerHeader header

Attributes description
decoration Set the top background color
child Configure child elements
padding Padding
margin Margin

UserAccountsDrawerHeader user information header

Attributes description
decoration Set the top background color
accountName account name
accountEmail Account email
currentAccountPicture profile picture
otherAccountsPictures Used to set other account avatars of the current account
margin Margin

Sidebar routing jump

onTap: (){ 
    Navigator.of(context).pop();
    Navigator.pushNamed(context, '/search'); 
}
 
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(this._titleList[this._currentIndex])),
      body: this._pageList[this._currentIndex],
      drawer: Drawer(//Text(' ')
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                 //child: DrawerHeader(
                 //  child: Text(' flutter'),
                 //  decoration: BoxDecoration(
                 //      color: Colors.yellow,
                 //      image: DecorationImage(
                 //          image: NetworkImage(
                 //              'https://www.itying.com/images/flutter/2.png'),
                 //          fit: BoxFit.cover)),
                 //),

                  child: UserAccountsDrawerHeader(
                    accountName: Text(' '), 
                    accountEmail: Text('miaomiao@123.com'), 
                    currentAccountPicture: CircleAvatar(
                      backgroundImage: NetworkImage('https://www.itying.com/images/flutter/4.png'),
                    ),
                    decoration: BoxDecoration(//
                        image: DecorationImage(
                            image: NetworkImage( 'https://www.itying.com/images/flutter/2.png'), fit: BoxFit.cover)
                    ),
                  ),
                )
              ],
            ),
            
            ListTile(
                leading: CircleAvatar(child: Icon(Icons.home)),
                title: Text(' '),
                onTap: (){
                  Navigator.of(context).pop();//
                  Navigator.pushNamed(context, '/login');
                },
            ),
            Divider(),
            ListTile(
                leading: CircleAvatar(child: Icon(Icons.phone)),
                title: Text(' ')),
            Divider(),
            ListTile(
                leading: CircleAvatar(child: Icon(Icons.settings)),
                title: Text(' '))
          ],
        ),
      ),
      endDrawer: Drawer(child: Text(' ')),
    );
  }

 

2020.03.09

Button component

Common button components are:RaisedButton FlatButton IconButton OutlineButton ButtonBar FloatingActionButton

  • RaisedButton: The raised button is actually the Material Design style Button
  • FlatButton : Flat button
  • OutlineButton: Wireframe button
  • IconButton : Icon button
  • ButtonBar: Button group FloatingActionButton: Floating button
Attribute name Value type Attribute value
onPressed VoidCallback, generally receives a method Required parameter, the callback triggered when the button is pressed, receives a method, pass null to indicate that the button is disabled, and the related styles of disabled will be displayed
child Widget Text control
textColor Color Text color
color Color Button color
disabledColor Color The color when the button is disabled
disabledTextColor Color The color of the text when the button is disabled
splashColor Color The color of the water ripple when the button is clicked
highlightColor Color The color of the button after clicking the (long press) button
elevation double The range of the shadow, the larger the value, the larger the shadow range
padding Padding
shape Set the shape of the button RoundedRectangleBorde(borderRadius: BorderRadius.circular(10),)
class _ButtonPageState extends State<ButtonPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(' ')),
      body:Container(
       //padding: EdgeInsets.all(20),
        child:Column(children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
               Container(        //RaisedButton Container 
                 width: 200,
                 height: 60,
                 child: RaisedButton(
                    child: Text(' '),
                    onPressed: (){
                      print(' ');
                    },
                    textColor:Colors.orangeAccent,     //
                    color:Colors.white,                //
                   //padding: EdgeInsets.fromLTRB(50, 10, 50, 10),//
                    shape: RoundedRectangleBorder(           //
                      borderRadius:BorderRadius.circular(20)
                    ),
                   //shape: CircleBorder(//
                   // //side:BorderSide(color:Colors.red)
                   //),
                    splashColor: Colors.blue,         //
                    highlightColor:Colors.red,       //( ) 
                    elevation: 3.0,
                   //disabledColor:Colors.grey,          //
                   //disabledTextColor:Colors.black,     //
                  )
                ),
              ]),
              SizedBox(height: 50,),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Expanded(//
                    child: 
                      Container(        //RaisedButton Container 
                        height: 60,
                        margin: EdgeInsets.all(20),
                        child: RaisedButton(
                            child: Text(' --Expanded'),
                            color: Colors.blue,
                            textColor: Colors.white,
                            onPressed: (){
                              print(' ');
                            },
                          )
                      ),
                  )
              ]),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Expanded(//
                    child: 
                      Container(        //RaisedButton Container 
                        height: 60,
                        margin: EdgeInsets.all(20),
                        child: FlatButton(
                            child: Text(' , '),
                            color: Colors.blue,
                            textColor: Colors.white,
                            onPressed: (){
                            },
                          )
                      ),
                  )
              ]),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Expanded(//
                    child: 
                      Container(        
                          child:ButtonBar(children: <Widget>[
                            Icon(Icons.home),
                            Icon(Icons.people),
                            Icon(Icons.wallpaper),
                            Icon(Icons.query_builder),
                          ],
                          alignment: MainAxisAlignment.spaceAround,
                          mainAxisSize:MainAxisSize.max,
                          buttonPadding: EdgeInsets.all(30),
                       )
                      ),
                  )
              ]),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Expanded(//
                    child: 
                      Container(        //RaisedButton Container 
                        height: 60,
                        margin: EdgeInsets.all(20),
                        child: OutlineButton(
                            child: Text(' '),
                            onPressed: (){
                            },
                          )
                      ),
                  )
              ]),

        ],)
      ),
     //
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add,color: Colors.yellow,size: 44,),
        onPressed: (){},
        backgroundColor: Colors.red,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}
 

FloatingActionButton floating button component

Attribute name Attribute value
child Sub-view, generally Icon, text is not recommended
tooltip FAB is displayed when long-pressed, which is also an accessibility feature
backgroundColor background color
elevation Shadow when not clicked
hignlightElevation The shadow value when clicked, the default is 12.0
onPressed Click event callback
shape You can define the shape of FAB, etc.
mini Whether it is a mini type, the default is false

FloatingActionButton FAB , Can realize the floating button, and can also realize the raised navigation similar to the Xianyu app

  • Floating button:floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  • Realize the raised button at the bottom of the Xianyu app

In the Scaffold()realization in

//floatingActionButton 
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, 
//FloatingActionButton   app  
floatingActionButton:Container(
    width: 60,
    height: 60,
   //padding: EdgeInsets.all(10),
    margin: EdgeInsets.only(top:15),
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(40),
      color: Colors.red,
    ),
   //color: Colors.red,
    child: FloatingActionButton(
      child: Icon(Icons.add,size: 44,),
      backgroundColor: this._currentIndex == 1 ? Colors.red :Colors.blue,//
      elevation: 0.0,//
      highlightElevation: 12.0 ,// 12.0
      onPressed: (){//
        print('FloatingActionButton');
        setState(() { 
          this._currentIndex = 1;
        });
      },
     //tooltip:'9900' ,//FAB  
     //shape:RoundedRectangleBorder(// FAB  
     //     borderRadius: BorderRadius.circular(10),//
     //),
     //shape: CircleBorder(//
     //  side: BorderSide(
     //      color: Colors.white,
     //  )
     //),
),
 

Tooltip long press effect:

Width adaptive:width:double.infinity

Form

TextField single-line text box, TextField multi-line text box

Attributes description
maxLines Set this parameter to change the text box to a multi-line text box
onChanged Event triggered when the text box is changed
decoration hintText: similar to placeholder in html;
- border: Configure the border of the text box to be used in conjunction with OutlineInputBorder
- labelText: the name of the label
- labelStyle: configure label style
obscureText Change the text box to the password box
controller The controller combined with TextEditingController() can configure the content displayed by default in the form

CheckBox, CheckboxListTile multi-select box component

Radio, RadioListTile radio button components

Switch, SwitchListTile

Common attributes of Checkbox, Radio, Switch:

Attributes description
value Checkbox (true or false); Radio (0/1); Switch (true or false)
onChanged Event triggered when changing
activeColor Selected color, background color
checkColor The selected color, the color of the check mark in the Checkbox

Common properties of CheckboxListTile:

Attributes description
value true or false
onChanged Event triggered when changing
activeColor Selected color, background color
title title
subtitle Secondary heading
secondary Configure icon or picture
selected Whether the text color changes when selected

Learning is over for now~