flutter框架一文通(一)

第一部分 vscode终端操作快捷键 第二部分 hello world程序 第三部分 常用组件

附:

flutter中文文档https://flutterchina.club/docs/
书籍:flutter实战 https://book.flutterchina.club/
flutter自动代码生成器 https://ui.flutterdart.cn/

第一部分 vscode终端操作快捷键:

运行模拟器:flutter run

更新页面:R

显示网格:P

android/IOS模式切换:O

关闭终端:Q

热更新方法:用debug,按照VS的提示配置即可,配置完成后 如下

image

第二部分. 框架简介及hello world

一、总体架构

1、总体架构

image

其中engine部分 :

  • skia 图形UI框架

  • dart 虚拟机dartVM

  • text 渲染纹理

其中Framework部分:

  • foundation:功能接口

  • animation: 动画

  • painting:图像

  • gestures:触控

  • rendering:渲染

  • widgets:组件

  • meterial:googleUI风格

  • cupertino:IOSUI风格

2、GPU渲染

image

3.状态控制

image

4.Flutter理论基础知识

二、写一个hello world程序

主程序在main.dart里

image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp());         //main函数只有一句话:运行APP

class MyApp extends StatelessWidget{    //app继承于StatelessWidget组件对象
  @override                             //重构build方法
  Widget build(BuildContext context){  //组件的build的方法返回一个组件 参数是其上下文文件
    return MaterialApp(                 //返回方法 返回组件
      title: "welcome",                 //APP的title
      home: Scaffold(                   //APP的主体,其类型是一个脚手架Scaffold
        appBar: AppBar(                 //脚手架第一个组成是appbar
          title: Text("welcome to big bear's flutter!!!"),  //appbar的title
        ),
        body: Center(            //脚手架的第二个组成是body 给body一个center组件做内容
          child: Text("hello 熊爸haha!"),   //center里有一个子组件是 Text("???")
        ),
      ),
    );
  }
}
image

第三部分 常用静态组件

statelesswidget 无状态变化的组件

statefullwidget 有状态变化的组件

一、文字组件 Text("")

image

1.textAlign (文本对齐)

Text的子属性,可传入TextAlign类对象,比如:

TextAlign.center 居中

TextAlign.left 左对齐

TextAlign.right 右对齐

TextAlign.start 和文字开始对齐

TextAlign.end 和文字结束对齐

image

2. maxLines (最大显示行数)

Text的子属性,可传入数值

Text(
            "hello 熊爸haha!锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。",
            textAlign: TextAlign.end,
            maxLines: 1,
            )

3. overflow 溢出处理

Text的子属性,可传入TextOverflow类对象

\begin{array}[a] {|a|ca|} \hline 对象 & 对象名称\ \hline TextOverflow.clip & 溢出裁剪 \ \hline TextOverflow.ellipsis & 溢出显示... \ \hline TextOverflow.fade &最后一行上下渐变 \ \hline \end{array}\

image

4. style 文字样式

Text的子属性,可传入TextStyle类对象

TextStyle类对象:

image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp());         //main函数只有一句话:运行APP

class MyApp extends StatelessWidget{    //app继承于StatelessWidget组件对象
  @override                             //重构build方法
  Widget build(BuildContext context){   //组件的build的方法返回一个组件 参数是其上下文文件
    return MaterialApp(                 //返回方法 返回组件
      title: "welcome",                 //APP的title
      home: Scaffold(                   //APP的主体,其类型是一个脚手架Scaffold
        appBar: AppBar(                 //脚手架第一个组成是appbar
          title: Text("welcome to big bear's flutter!!!"),  //appbar的title
        ),
        body: Center(                   //脚手架的第二个组成是body 给body一个center组件做内容
          child: Text(
            "hello 熊爸熊爸熊爸haha!锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。",
            textAlign: TextAlign.left,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(
              fontSize: 25.0,
              color:Color.fromARGB(255, 220, 125, 125),
              decoration: TextDecoration.underline,
              decorationStyle: TextDecorationStyle.wavy,
            ),
            ), //center里有一个子组件是 Text("???")
        ),
      ),
    );
  }
}
image

二、container组件 container() 容器

container() 相当于HTML里的div

image
image
image
image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp());         //main函数只有一句话:运行APP

class MyApp extends StatelessWidget{    //app继承于StatelessWidget组件对象
  @override                             //重构build方法
  Widget build(BuildContext context){  //组件的build的方法返回一个组件 参数是其上下文文件
    return MaterialApp(                 //返回方法 返回组件
      title: "welcome",                 //APP的title
      home: Scaffold(                   //APP的主体,其类型是一个脚手架Scaffold
        appBar: AppBar(                 //脚手架第一个组成是appbar
          title: Text("welcome to big bear's flutter!!!"),  //appbar的title
        ),
        body: Center(            //脚手架的第二个组成是body 给body一个center组件做内容
          child: Container(
            height: 400.0,
            width: 300.0,
            //color: Colors.pinkAccent,
            margin: EdgeInsets.symmetric(horizontal: 010.0),
            decoration: new BoxDecoration(
              gradient: const LinearGradient(colors: [Colors.lightBlue,Colors.green],
                                            begin: Alignment.topLeft,
                                            end: Alignment.bottomRight,
                                            tileMode: TileMode.clamp,
                                            ),
              border: Border.all(width: 2.0,color: Colors.blueGrey),
              ),
            transform: Matrix4.rotationZ(0.1),
            alignment: Alignment.topLeft,
            padding: const EdgeInsets.fromLTRB(15.0, 30.0, 15.0, 0),
            child: Text(
              "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦!",
              style: TextStyle(
                fontSize: 24.0,
              ),
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              textAlign: TextAlign.center,
            ),
          ),   //center里有一个子组件是 Text("???")
        ),
      ),
    );
  }
}
image

三. image组件

image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp());         //main函数只有一句话:运行APP

class MyApp extends StatelessWidget{    //app继承于StatelessWidget组件对象
  @override                             //重构build方法
  Widget build(BuildContext context){  //组件的build的方法返回一个组件 参数是其上下文文件
    return MaterialApp(                 //返回方法 返回组件
      title: "welcome",                 //APP的title
      home: Scaffold(                   //APP的主体,其类型是一个脚手架Scaffold
        appBar: AppBar(                 //脚手架第一个组成是appbar
          title: Text("welcome to big bear's flutter!!!"),  //appbar的title
        ),
        body: Center(            //脚手架的第二个组成是body 给body一个center组件做内容
          child: Container(
            height: 600.0,
            width: 400.0,
            color: Colors.lightBlue,
            child: Image.network(
              "http://cms-bucket.ws.126.net/2019/1228/d84b26e0p00q37jrh002uc0009c005uc.png?imageView&thumbnail=200y140",
              fit: BoxFit.scaleDown,
              repeat: ImageRepeat.repeat,
              color: Colors.pinkAccent,
              colorBlendMode: BlendMode.darken,
            )
          ), 
        ),
      ),
    );
  }
}

四. Align组件 //对齐组件

image
image

五. Scaffold组件 //(脚手架)

脚手架是flutter页面框架结构中最重要的一环,他是页面的框架骨骼基础

image

六. AppBar组件 //APP导航条

image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(
        leading: Icon(Icons.home),
        title: Text("AppBar示例"),
        centerTitle: true,
        backgroundColor: Colors.deepPurpleAccent,
        actions: [
          IconButton(icon: Icon(Icons.print), tooltip: 'print', onPressed: () {}),
          IconButton(icon: Icon(Icons.plus_one), tooltip: 'more', onPressed: () {}),
          IconButton(icon: Icon(Icons.share), tooltip: 'share', onPressed: () {}),
          PopupMenuButton(itemBuilder: 
            (context)=>>[
              PopupMenuItem(
                value: "share",
                child: Text("分享到朋友圈"),
              ),
              PopupMenuItem(
                value: "quit",
                child: Text("退出"),
              )
            ]
          )
        ],
      ),
        body: Container(),
      ),
    );
  }
}
image
image

七. FloatingActionButton //悬浮按钮组件

image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(
          title: Text("data"),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(
          tooltip: "小贴士,解释按键后会发生什么",
          foregroundColor: Colors.black87,
          backgroundColor: Colors.amberAccent,
          hoverColor: Colors.deepPurple,
          focusColor: Colors.deepPurpleAccent,
          splashColor: Colors.greenAccent,
          highlightElevation: 5,
          hoverElevation: 15,
          elevation: 5,
          focusElevation: 10,
          autofocus: true,
          mini: true,
          child: Icon(Icons.add),
          onPressed: () {},
        ),
        body: Container(),
      ),
    );
  }
}
image

八. BottomAppBar组件 //底部导航条

image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("data"),),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: (){},
        ),

        bottomNavigationBar: BottomAppBar(
          notchMargin: 10.0,
          color: Colors.amber, 
          elevation: 10,
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
           children: [
             IconButton(icon: Icon(Icons.search), onPressed: (){}),
             IconButton(icon: Icon(Icons.menu), onPressed: (){}),
           ], 
          ),
        ),
        body: Container(),
      ),
    );
  }
}
image

九. ButtonBar //按钮条组件

image
image
image

十. NestedScrollView //可嵌套的滚动视图结构

image
image

十一. SliverAppBar //可扩展折叠的滚动工具栏

SliverAppBar 必须作为NestedScrollView 的子项才有用!!!!

image

十一. FlexibleSpaceBar组件 //可折叠空间组件

FlexibleSpaceBar必须作为SliverAppBar的子项才有用!!!!

image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(
          title: Text("data"),
        ),
        body: NestedScrollView(
            headerSliverBuilder: (context, beScrolled) {
              return [
                (
                  centerTitle: true,
                  expandedHeight: 200,
                  floating: false,
                  pinned: true,
                  flexibleSpace: FlexibleSpaceBar(
                    background: Image.network(
                      "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=793051438,2878586275&fm=11&gp=0.jpg",
                      fit: BoxFit.cover,
                    ),
                    title: Text("可折叠组件"),
                  ),
                )
              ];
            },
            body: Center()),
      ),
    );
  }
}
image

十二. listView组件 列表布局

ListView的children是组件类型,所以可以随便添加任意组件

image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp());         //main函数只有一句话:运行APP

class MyApp extends StatelessWidget{    //app继承于StatelessWidget组件对象
  @override                             //重构build方法
  Widget build(BuildContext context){  //组件的build的方法返回一个组件 参数是其上下文文件
    return MaterialApp(                 //返回方法 返回组件
      title: "welcome",                 //APP的title
      home: Scaffold(                   //APP的主体,其类型是一个脚手架Scaffold
        appBar: AppBar(                 //脚手架第一个组成是appbar
          title: Text("welcome to big bear's flutter!!!"),  //appbar的title
        ),
        body: Center(
          child: Container(
            height: 200,
            color: Colors.pinkAccent,
            child: MyList001(),
          ),
        )
      ),
    );
  }
}
class MyList001 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ListView(
              scrollDirection: Axis.horizontal,
              children: [
              Container(width: 180,color: Colors.lightBlue,),  
              Container(width: 180,color: Colors.pinkAccent,),
              Container(width: 180,color: Colors.lightGreen,),
              Container(width: 180,color: Colors.deepPurple,),                    
              ],
            );
  }
}

动态列表(参数传递内容的列表)

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp(
  items:List.generate(15,(i)=>"Item $i")  //在myapp类里创建了一个属性叫items,它里面有一个列表
                      //里面的(i)=>"Item $i"是自动生成列表的项,就像python 列表中可以写lambda表达式一样
));

class MyApp extends StatelessWidget{    
  final List items;            //类中建立属性items 
  MyApp({Key key,@required this.items}):super(key:key); 
  //Key key                  重写构造函数默认传入的
  //@required this.items     限定修饰  this.items必须传入
  //:super(key:key) 调用祖先/父类无名无参构造函数,StatelessWidget 所以需要super往上找
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(                   
        body:ListView.builder(               //用专门的builder方法构建动态列表
          itemCount: items.length,           //传入项目的数量
          itemBuilder: (context,index){      //传入context上下文,同时传入index 
                                             //这里有点像JS,把下文中需要的参数实现一下
            return ListTile(                 //listTile listview的项目瓦片
              title: Text("${items[index]}"), //通过重构函数,我们将外部的信息传入了动态列表中
            );
          },
        )
      ),
    );
  }
}

十三. 网格列表布局

image
import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("dasdasdas"),
        ),                   
        body:MyGridList(),
      ),
    );
  }
}
class MyGridList extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return GridView.count(
          padding: EdgeInsets.all(5.0),
          crossAxisSpacing:5,
          crossAxisCount: 3,
          mainAxisSpacing: 5,
          childAspectRatio: 0.7,
          children: [
            Image.network("https://image11.m1905.cn/uploadfile/2019/0829/thumb_1_150_203_20190829041446876955.jpg",fit: BoxFit.cover,),
            Image.network("https://image11.m1905.cn/uploadfile/2019/1227/thumb_1_150_203_20191227090512473043.jpg",fit: BoxFit.cover,),
            Image.network("https://image11.m1905.cn/uploadfile/2019/0123/thumb_1_150_203_20190123044311875088.jpg",fit: BoxFit.cover,),
            Image.network("https://image11.m1905.cn/uploadfile/2018/0209/thumb_1_150_203_20180209015612332245.jpg",fit: BoxFit.cover,),
            Image.network("https://image11.m1905.cn/uploadfile/2014/0812/thumb_1_150_203_20140812031906771224.jpg",fit: BoxFit.cover,),
            Image.network("https://image11.m1905.cn/uploadfile/2009/1106/thumb_1_150_203_20091106112530726.jpg",fit: BoxFit.cover,),
            Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2577327061.webp",fit: BoxFit.cover,),
            Image.network("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg",fit: BoxFit.cover,),
            Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2556824333.jpg",fit: BoxFit.cover,),
            Image.network("https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2574764569.jpg",fit: BoxFit.cover,),
            Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2568258113.jpg",fit: BoxFit.cover,),
            Image.network("https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541280047.jpg",fit: BoxFit.cover,),
          ],
          );
  }
}

按拓展性构建动态网格

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MaterialApp(
      title: "组件",
      home: MyApp(),
    )); //main函数只有一句话:运行APP

class MyApp extends StatelessWidget {
  List _buildList(int count) {
    return List.generate(
      count,
      (int index) => Container(child: Image.asset('images/${index + 1}.jpg')),
    );
  }

  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    return Scaffold(
      appBar: AppBar(
        title: Text("data"),
      ),
      body: GridView.extent(
        maxCrossAxisExtent: 150.0,
        padding: EdgeInsets.all(4.0),
        mainAxisSpacing: 4.0,
        crossAxisSpacing: 4.0,
        children: _buildList(9),
      ),
    );
  }
}
image

十四. 按钮组件

image

十五. 水平布局

Row组件水平布局,搭配Expanded组件 可实现灵活的水平布局

对Row来说 主轴是水平方向

image
image
image
image
import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("熊爸"),
        ),                   
        body:Row(

          children: [
            RaisedButton(
              onPressed: (){print("点击了");},
              color: Colors.amberAccent,
              child: Text("amberAccent"),
            ),
            Expanded(child: RaisedButton(
              onPressed: (){print("点击了");},
              color: Colors.lightBlue,
              child: Text("lightBlue"),
            ),),
            Expanded(child: RaisedButton(
              onPressed: (){print("点击了");},
              color: Colors.pinkAccent,
              child: Text("pinkAccent"),
            ),)
          ],
        ),
      ),
    );
  }
}

十六. 垂直布局

image

对Row来说 主轴是垂直方向

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("熊爸"),
        ),                   
        body:Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text("熊爸"),
            Expanded(child: Text("锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。"),),
            Text("data"),
          ],
        ),
      ),
    );
  }
}

十七. Stack组件、Position组件(层叠布局 )

两层堆叠用Stack组件

多层堆叠用Position组件

image
image
image
import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("熊爸"),
        ),                   
        body:Stack(
          alignment: FractionalOffset(0.5,0.9),
          children: [
            CircleAvatar(child: Text("一部电影"),radius: 200,foregroundColor: Colors.purple,backgroundImage: NetworkImage("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg"),),
            Container(
              width: 100,
              height: 50,
              color: Colors.lightBlue,
              alignment: Alignment.center,
              child: Text("本月最佳",style: TextStyle(color: Colors.white),),
            )
          ],
        ),
      ),
    );
  }
}
image
import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("熊爸"),
        ),                   
        body:Stack(
          alignment: FractionalOffset(0.5,0.9),
          children: [
            CircleAvatar(child: Text("一部电影"),radius: 200,foregroundColor: Colors.purple,backgroundImage: NetworkImage("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg"),),
            Positioned(
              top: 10.0,
              left: 20.0,
              child: Text("haha")
            ),
            Positioned(
              bottom: 10.0,
              right: 20.0,
              child: Text("OKOK")
            ),
          ],
        ),
      ),
    );
  }
}

十八. 圆盘组件

image

十九. 瓦片组件

image

二十. 卡片布局

image
import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());

class MyApp extends StatelessWidget{    
  @override                             
  Widget build(BuildContext context){  
    return MaterialApp(                 
      title: "welcome",                 
      home: Scaffold(
        appBar: AppBar(
          title: Text("熊爸"),
        ),                   
        body:Card(
          borderOnForeground: true,
          child: Column(
            children: [
              ListTile(
                title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
                subtitle: Text("a lovely girl"),
                leading: CircleAvatar(backgroundImage: NetworkImage("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2572847101.webp"),),
              ),
              Divider(),
              ListTile(
                title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
                subtitle: Text("a lovely girl"),
                leading: Icon(Icons.satellite),
                trailing: Icon(Icons.keyboard_arrow_right),
              ),
              Divider(),
              ListTile(
                title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
                subtitle: Text("a lovely girl"),
                leading: Icon(Icons.satellite),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

例2:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("FlatButton")),
        body: Column(
          children: [
            Card(
              color: Colors.red[100],
              margin: EdgeInsets.all(10),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ListTile(
                    leading: Icon(Icons.shopping_basket),
                    title: Text(
                      "一加手机 OnePlus7pro",
                      style: TextStyle(fontSize: 25),
                    ),
                    subtitle: Text("8+256G"),
                    contentPadding: EdgeInsets.all(10),
                    trailing: Text(
                      "¥3999",
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                  ButtonBar(
                    children: [
                      FlatButton.icon(
                          textColor: Colors.deepPurple,
                          onPressed: () {},
                          icon: Icon(Icons.shopping_cart),
                          label: Text("购买")),
                      FlatButton.icon(
                          textColor: Colors.redAccent,
                          onPressed: () {},
                          icon: Icon(Icons.favorite),
                          label: Text("收藏")),
                    ],
                  )
                ],
              ),
            ),
            Card(
              color: Colors.orange,
              margin: EdgeInsets.all(10),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ListTile(
                    leading: Icon(Icons.shopping_basket),
                    title: Text(
                      "小米手机 CC9",
                      style: TextStyle(fontSize: 25),
                    ),
                    subtitle: Text("8+256G"),
                    contentPadding: EdgeInsets.all(10),
                    trailing: Text(
                      "¥1999",
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                  ButtonBar(
                    children: [
                      FlatButton.icon(
                          textColor: Colors.deepPurple,
                          onPressed: () {},
                          icon: Icon(Icons.shopping_cart),
                          label: Text("购买")),
                      FlatButton.icon(
                          textColor: Colors.redAccent,
                          onPressed: () {},
                          icon: Icon(Icons.favorite),
                          label: Text("收藏")),
                    ],
                  )
                ],
              ),
            ),
            Card(
              color: Colors.green,
              margin: EdgeInsets.all(10),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ListTile(
                    leading: Icon(Icons.shopping_basket),
                    title: Text(
                      "OPPO手机 FindX2",
                      style: TextStyle(fontSize: 25),
                    ),
                    subtitle: Text("8+256G"),
                    contentPadding: EdgeInsets.all(10),
                    trailing: Text(
                      "¥3599",
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                  ButtonBar(
                    children: [
                      FlatButton.icon(
                          textColor: Colors.deepPurple,
                          onPressed: () {},
                          icon: Icon(Icons.shopping_cart),
                          label: Text("购买")),
                      FlatButton.icon(
                          textColor: Colors.redAccent,
                          onPressed: () {},
                          icon: Icon(Icons.favorite),
                          label: Text("收藏")),
                    ],
                  )
                ],
              ),
            ),
            Card(
              color: Colors.blueGrey,
              margin: EdgeInsets.all(10),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ListTile(
                    leading: Icon(Icons.shopping_basket),
                    title: Text(
                      "华为手机 Mate30",
                      style: TextStyle(fontSize: 25),
                    ),
                    subtitle: Text("8+256G"),
                    contentPadding: EdgeInsets.all(10),
                    trailing: Text(
                      "¥3799",
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                  ButtonBar(
                    children: [
                      FlatButton.icon(
                          textColor: Colors.deepPurple,
                          onPressed: () {},
                          icon: Icon(Icons.shopping_cart),
                          label: Text("购买")),
                      FlatButton.icon(
                          textColor: Colors.redAccent,
                          onPressed: () {},
                          icon: Icon(Icons.favorite),
                          label: Text("收藏")),
                    ],
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
image

二十一. 分割线组件

Divider()

二十二. 导航

Navigator.push(context, route); //压栈,压入下一页

Navigator.pop(context); //弹栈,弹出一层

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MaterialApp(
      title: "组件",
      home: MyApp(),
    )); //main函数只有一句话:运行APP

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第一页"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("进入第二页"),
          onPressed: () {
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => SecondPage()));
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第二页"),
      ),
      body: Column(
          children: [
            RaisedButton(
              child: Text("返回"),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            RaisedButton(
              child: Text("进入第三页"),
              onPressed: (){
                Navigator.push(context, MaterialPageRoute(builder: (context)=>ThirdPage()));
              },
            ),
          ],
        ),
    );
  }
}

class ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第三页"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("返回"),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    return FirstPage();
  }
}
image

二十三. 带参数传递的导航

Navigator.push(context, MaterialPageRoute(builder: ( (context)=>SecPage(product: products[index],) )));

其实就是在构造函数中传递.

import 'package:flutter/material.dart';

class Product {
  final String title;
  final String description;
  Product(this.title,this.description);
}
void main() {
  runApp(MyApp(products: List.generate(50,(i)=>Product("商品$i","这是一个商品详情,编号为$i")),));
}

class MyApp extends StatelessWidget {
  final List products;
  const MyApp({Key key,@required this.products}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
    title: "test1",
    home: ProductList(
      products:List.generate(products.length, (i)=>products[i])),
    );
  }
}
class ProductList extends StatelessWidget {
  final List products;
  const ProductList({Key key,@required this.products}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("products"),),
      body: ListView.builder(
        itemCount: products.length,
        itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text(products[index].title),
          onTap: (){
            Navigator.push(context, MaterialPageRoute(
              builder: (context)=>SecondPage(product: products[index],)
            ));
          },
        );
       },
      ),
      );
  }
}
class SecondPage extends StatelessWidget {
  final Product product;
  const SecondPage({Key key,@required this.product}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("商品详情"),),
      body: Text(product.description),
    );
  }
}

例二:页面跳转发送数据

import 'package:flutter/material.dart';

class Product {
  final String title;
  final String description;
  Product(this.title, this.description);
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "页面间数据传递",
      home: ProductList(
        products: List.generate(20, (i) => "$i"),
      ),
    );
  }
}

class ProductList extends StatelessWidget {
  final List products;
  ProductList({Key key, @required this.products}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("商品汇总页")),
        body: ListView.builder(
          itemCount: products.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text("这是商品:$index"),
              onTap: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: ((context) => SecPage(
                              product: Product("$index","这件$index 号商品是我们村的爆款哦!"),
                            ))));
              },
            );
          },
        ));
  }
}

class SecPage extends StatelessWidget {
  final Product product;
  SecPage({Key key, @required this.product}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("$product 的商品详情")),
      body: Center(
        child: Column(
          children: [
            Text(
              "商品显示在这里,商品编号:${product.title},\n商品描述:${product.description}.\n它$product 非常诱人!!\n您还在犹豫个啥???",
              style: TextStyle(fontSize: 20),
            ),
            RaisedButton(
              child: Text("返回"),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}
image

例三:页面跳转返回数据

二十四. 异步请求和等待

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main(){
  runApp(MaterialApp(
    title: "页面跳转",
    home:FirstPage(),
  ));
}
class FirstPage extends StatelessWidget {
  const FirstPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("dataa"),),
      body: Center(child:RouteBut()),
    );
  }
}
class RouteBut extends StatelessWidget {
  const RouteBut({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      shape: StadiumBorder(),
      onPressed: (){
        _navi_in(context);
      },
      color: Colors.lightBlue,
      child: Text("进入"),
    );
  }
  _navi_in(BuildContext context) async{
    final result=await Navigator.push(context,
    MaterialPageRoute(
      builder: (contex)=>SecondPage()
    )
    );
    Scaffold.of(context).showSnackBar(SnackBar(content: Text(result),));
  }
}
class SecondPage extends StatelessWidget {
  const SecondPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Scaffold(
        appBar: AppBar(title: Text("设置返回数据"),),
        body: Center(
          child: Column(
            children: [
              RaisedButton(
                child: Text("返回数据1"),
                onPressed: (){
                  Navigator.pop(context,"数据1");
                },
              ),
              RaisedButton(
                child: Text("返回数据2"),
                onPressed: (){
                  Navigator.pop(context,"数据2");
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

二十五. 加载静态资源

在项目里创建一个资源文件夹,放入资源

image

找到pubspec.yaml文件并打开

image

注册资源:

image

注册后就可以引用了

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main()=>runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      title: "myAPP",
      home: Scaffold(
        appBar: AppBar(title: Text("daaata"),),
        body:Container(
          child: Image.asset("images/test1.jpg"),
        )
      ),
    );
  }
}

二十六. Expanded //拓展组件

Expanded 组件可以让 Row、Column、Flex等子组件在其主轴方向上展开并填充可用空间。类似 Android 中的 widget 属性的用法

image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MyApp()); //main函数只有一句话:运行APP

class MyApp extends StatelessWidget {
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    final mytitle = "listview";
    return MaterialApp(
      //返回方法 返回组件
      title: mytitle, //APP的title
      home: Scaffold(
          //APP的主体,其类型是一个脚手架Scaffold
          appBar: AppBar(
            //脚手架第一个组成是appbar
            title: Text(mytitle), //appbar的title
          ),
          body: Row(
            children: [
              Image.network(
                "https://i0.hdslb.com/bfs/bangumi/b919ca54abfa2aaed952f197da67211118944923.jpg@144w_144h.webp",
                width: 50,
              ),
              Text("这是一个非常非常非常非常长的句子!!!长到这个ROW放不下了!!!"),
              Icon(Icons.sentiment_satisfied),
            ],
          )),
    );
  }
}
image

如果用上expanded组件则:

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MyApp()); //main函数只有一句话:运行APP

class MyApp extends StatelessWidget {
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    final mytitle = "listview";
    return MaterialApp(
      //返回方法 返回组件
      title: mytitle, //APP的title
      home: Scaffold(
          //APP的主体,其类型是一个脚手架Scaffold
          appBar: AppBar(
            //脚手架第一个组成是appbar
            title: Text(mytitle), //appbar的title
          ),
          body: Row(
            children: [
              Image.network(
                "https://i0.hdslb.com/bfs/bangumi/b919ca54abfa2aaed952f197da67211118944923.jpg@144w_144h.webp",
                width: 50,
              ),
              Expanded(child: Text("这是一个非常非常非常非常长的句子!!!长到这个ROW放不下了!!!所以expanded组件就自动修改了一下文本样式,终于让ROW能显示了!!!"),),
              Icon(Icons.sentiment_satisfied),
            ],
          )),
    );
  }
}
image

二十七. sizebox盒模型

image

二十八. GestureDetector组件(手势监听)

image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MaterialApp(
      title: "组件",
      home: MyApp(),
    )); //main函数只有一句话:运行APP

class Mybutton extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: (){
        final mysnak=SnackBar(content: Text("触发ontap,冒出提示框!!"));
        Scaffold.of(context).showSnackBar(mysnak);
      },
      child: Container(
       padding: EdgeInsets.all(12.0),
       decoration: BoxDecoration(
       color: Theme.of(context).buttonColor,
       borderRadius: BorderRadius.circular(10.0),  
       ), 
       child: Text("点一下"),
      ),
    );
  }
}
class MyApp extends StatelessWidget {
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    return Scaffold(
      appBar: AppBar(
        title: Text("data"),
      ),
      body: Center(child:Mybutton()),
    );
  }
}
image

二十九. Dismissible组件(滑动删除)

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MaterialApp(
      title: "组件",
      home: MyApp(),
    )); //main函数只有一句话:运行APP

class MyApp extends StatelessWidget {
  List items = List.generate(30, (i) => "item${i + 1}");
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    return Scaffold(
      appBar: AppBar(
        title: Text("data"),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return Dismissible(
            key: Key(items[index]),
            onDismissed: (derction) {
              items.removeAt(index);
              Scaffold.of(context)
                  .showSnackBar(SnackBar(content: Text("data:$derction")));
            },
            child: ListTile(
              title: Text("列表${items[index]}"),
            ),
          );
        },
      ),
    );
  }
}
image

三十. SnackBar

image
Scaffold.of(context).showSnackBar(SnackBar(content: Text("data:$derction")));

例2:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "TEST",
        home: Scaffold(
            appBar: AppBar(
              title: Text("data"),
            ),
            body: Center(
              child: MyBut1(),
            )));
  }
}

class MyBut1 extends StatelessWidget {
  final mySnak1 = SnackBar(
    content: Row(
      children: [
        Icon(Icons.cake),
        Text("感谢点击!!"),
      ],
    ),
    backgroundColor: Colors.deepPurpleAccent,
    //持续时间
    duration: Duration(milliseconds: 1500),
    //反馈动作
    action: SnackBarAction(
        label: "OK", textColor: Colors.greenAccent, onPressed: () {}),
  );
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text("点击出现snackBar"),
      onPressed: () {
        Scaffold.of(context).showSnackBar(mySnak1);
      },
    );
  }
}
image

三十一. 自定义字体

1.新建字体文件夹font 并放入字体文件

image

2.在pubspec.yaml文件中注册字体.

image

3.在程序中引用

import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO

void main() => runApp(MaterialApp(
      title: "组件",
      home: MyApp(),
    )); //main函数只有一句话:运行APP

class MyApp extends StatelessWidget {
  List items = List.generate(30, (i) => "item${i + 1}");
  //app继承于StatelessWidget组件对象
  @override //重构build方法
  Widget build(BuildContext context) {
    //组件的build的方法返回一个组件 参数是其上下文文件
    return Scaffold(
      appBar: AppBar(
        title: Text("data"),
      ),
      body: Center(
        child: Text(
          "自定d义字体1data!!?!!@#%@#abasdasdaxkl123454563",
          style: TextStyle(
            fontSize: 25,
            fontFamily: "xkzzt",
          ),
        ),
      ),
    );
  }
}

三十二. hero组件 //页面过度动画

image

注意:要过渡的两个页面应该设置同样的tag

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "test",
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第一页"),
      ),
      body: GestureDetector(
          child: Hero(
            tag: "pic1",
            child: Icon(Icons.picture_in_picture),),
          onTap: () {
            Navigator.push(
                context, MaterialPageRoute(builder: (contex) => SecPage()));
          },
      ),
    );
  }
}

class SecPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("第二页")),
      body: Center(
        child: GestureDetector(
          child: Hero(
            tag: "pic1",
            child: Image.network(
                "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1581017576843&di=e5876e0581a47faa82797803e4949794&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180910%2Ff96bbc903e094492a571515d0e417bf3.jpeg"),
          ),
          onTap: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}
image

三十三. ConstrainedBox //可伸缩盒子

伸缩盒子给子组件限定了一个最大和最小空间,子组件不得超过此空间.

image
image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "TEST",
        home: Scaffold(
          appBar: AppBar(title: Text("ConstrainedBox")),
          body: Container(
            height: 500,
            child: ConstrainedBox(
              constraints: BoxConstraints(
                maxWidth:300,              
                minHeight: 200,
                maxHeight: 500,
                minWidth: 200,
                ),
              child: Container(
                width: 0,
                height: 600, 
                color: Colors.redAccent,
              ),  
              ),
          ),
        ));
  }
}

三十四. DecoratedBox //带装饰的盒子

image
image
image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "TEST",
        home: Scaffold(
          appBar: AppBar(title: Text("bottomNavigatorBar")),
          body: Center(
            child: Container(
              width: 350,
              height: 600,
              child: DecoratedBox(
                position: DecorationPosition.foreground,
                //决定装饰器位置,会不会遮挡child里的组件
                decoration: BoxDecoration(
                  color: Colors.teal,
                  image: DecorationImage(
                    image: NetworkImage(
                        'http://a1.att.hudong.com/05/00/01300000194285122188000535877.jpg'),
                  ),
                  borderRadius: BorderRadius.circular(20),
                  backgroundBlendMode: BlendMode.colorBurn,
                  border: Border.all(
                    width: 6,
                    color: Colors.black38,
                  ),
                  //shape: BoxShape.rectangle
                ),
                child: Text(
                  "可爱可爱小猫咪",
                  style: TextStyle(fontSize: 25),
                ),
              ),
            ),
          ),
        ));
  }
}
image

三十五. FittedBox //自适应填充盒模型

此盒子允许他的子组件有自适应性

image
image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("FittedBox")),
        body: Column(
          children: [
            Container(
              width: 200,
              height: 100,
              color: Colors.greenAccent,
              child: FittedBox(
                fit: BoxFit.fill,
                alignment: Alignment.center,
                child: Text("使用fill模式自适应"),
              ),
            )
          ],
        ),
      ),
    );
  }
}
image

三十六. OverflowBox //允许溢出的盒模型

此盒子允许他的子组件溢出

image
image

三十七. RotatedBox //允许旋转盒模型

此盒子允许他的子组件旋转,会顺时针旋转 quarterTurns × 90°

image
image

注意data的方向

三十八. SizedBox //限定大小的盒模型

image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("RotatedBox")),
        body: SizedBox(
            width: 200,
            height: 200,
            child: Container(
              width: 400,
              height: 100,
              color: Colors.blue,
            )),
      ),
    );
  }
}
image

子组件设置了宽高,但不管用了

三十九. FlatButton //扁平按钮组件

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("FlatButton")),
        body: Center(
          child: Column(
            children: [
              FlatButton(
                child: Text("data"),
                colorBrightness: Brightness.dark,
                onHighlightChanged: (n) {},
                onPressed: () {},
                onLongPress: () {},
                color: Colors.pinkAccent,
              ),
              FlatButton.icon(
                  color: Colors.amberAccent,
                  onPressed: () {},
                  icon: Icon(Icons.history),
                  label: Text("null")),
            ],
          ),
        ),
      ),
    );
  }
}
image

四十. IconButton //图标按钮组件

image

四十一 OutlineButton //外边线按钮组件

image

四十二. RawMaterialButton //原始按钮组件

image

第四部分 常用动态组件

一. tabbar组件 //选项卡

选项卡是一个动态组件,动态组件创建如下:

image

创建步骤:

1.在appbar中加一个tabbar

2.在body中加一个tabbarview

3.制作一个控制器_tabController来关联上面的二者

4.重写initState() dispose() 用来实现上述控制器

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: "TEST", home: Demo());
  }
}

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();//重写创建状态
}

class _DemoState extends State with SingleTickerProviderStateMixin {//必须加SingleTickerProviderStateMixin
  ScrollController _scrollController;    //类内声明了一个ScrollController组件,名叫_scrollController
  TabController _tabController;//类内声明了一个TabController组件,名叫_tabController
  @override
  void initState() {        //重写初始化状态函数
    super.initState();      //必须先继承父类
    _scrollController = ScrollController();  //初始化时创建一个ScrollController,赋值给_scrollController
    _tabController = TabController(length: 6, vsync: this);//初始化时创建一个TabController,赋值给_tabController
    //length必须与选项卡数量对应  
  }

  @override
  void dispose() {   //重写释放函数
    _scrollController.dispose();  //注销_scrollController组件
    _tabController.dispose();//注销_tabController组件
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(Icons.home),
        title: Text("tabBar"),
        bottom: TabBar(          //在APPBAR的底部加一个tabbar
          controller: _tabController,   //控制器为_tabController
          tabs: [    //里面的Tab
            Tab(text: '语文',icon: Icon(Icons.font_download),),
            Tab(text: '数学',icon: Icon(Icons.format_list_numbered),),
            Tab(text: '英语',icon: Icon(Icons.nature),),
            Tab(text: '历史',icon: Icon(Icons.history),),
            Tab(text: '地理',icon: Icon(Icons.map),),
            Tab(text: '生物',icon: Icon(Icons.book),),
          ],
        ),
      ),
      body: TabBarView(  //在body里加一个TabBarView
        controller: _tabController,  //也用_tabController作为控制器,这样就能和tabbar对应起来
        children: [  //子元素个数应该和tabbar对应起来
          Text("语文"),
          Text("数学"),
          Text("英语"),
          Text("历史"),
          Text("地理"),
          Text("生物"),
        ],
      ),
    );
  }
}
image

二. 底部导航栏

image
image
image
image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "TEST",
        home: Scaffold(
          appBar: AppBar(title: Text("bottomNavigatorBar")),
          body: Container(
            height: 500,
          ),
          bottomNavigationBar: Demo(),
        ));
  }
}

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State {
  int _currentIndex = 1;
  void _onItemTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      onTap: _onItemTapped,
      type: BottomNavigationBarType.fixed,
      currentIndex: _currentIndex,
      items: [
        BottomNavigationBarItem(
          title: Text("book"),
          icon: Icon(Icons.book),
        ),
        BottomNavigationBarItem(
          title: Text("shop"),
          icon: Icon(Icons.shop),
        ),
        BottomNavigationBarItem(
          title: Text("music"),
          icon: Icon(Icons.queue_music),
        ),
      ],
    );
  }
}
image

三. 下拉按钮组件

image
image
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "TEST",
      home: Scaffold(
        appBar: AppBar(title: Text("DropdownButDemo")),
        body: Center(
          child: DropdownButDemo(),
        ),
      ),
    );
  }
}

class DropdownButDemo extends StatefulWidget {
  @override
  _DropdownButDemoState createState() => _DropdownButDemoState();
}

class _DropdownButDemoState extends State with SingleTickerProviderStateMixin {
  int _cureentValue=1;
  List dropItemsList(){
    final List mitems=List();
    final DropdownMenuItem item1 =DropdownMenuItem(child: Text("book"),value: 1);
    final DropdownMenuItem item2 =DropdownMenuItem(child: Text("shop"),value: 2);
    final DropdownMenuItem item3 =DropdownMenuItem(child: Text("cake"),value: 3);
    final DropdownMenuItem item4 =DropdownMenuItem(child: Text("bank"),value: 4);
    mitems.add(item1);
    mitems.add(item2);
    mitems.add(item3);
    mitems.add(item4);
    return mitems;
  }
  @override
  Widget build(BuildContext context) {
    return DropdownButton(
      value: _cureentValue,
      items: dropItemsList(),//下拉列表
      hint: Text("请下拉"),//提示文本
      iconSize: 48,//图标大小
      elevation: 10,//阴影
      isExpanded: true,//继承父容器的大小
      focusColor: Colors.redAccent, //获得焦点的颜色
      iconEnabledColor: Colors.amber,//按钮可用时的颜色
      iconDisabledColor: Colors.grey,//按钮不可用时的颜色
      icon: Icon(Icons.keyboard_arrow_down),
      style: TextStyle(fontSize: 30,color: Colors.black54,),//字体样式
      isDense:true,
      itemHeight:80,
      autofocus: true,
      onChanged: (T){
        setState((){
          _cureentValue=T;
        });
      }, 
    );
  }
}
image

第五部分 打包与发布

Android打包(VScode)

一 配置APP图标

图标目录: /android/app/src/main/res/

进入之后你会看到很多mipmap-为前缀命名的文件夹,后边的是像素密度,可以看出图标的分辨率。

  • mdpi (中) ~160dpi

  • hdpi (高) ~240dip

  • xhdpi (超高) ~320dip

  • xxhdpi (超超高) ~480dip

  • xxxhdpi (超超超高) ~640dip

将对应像素密度的图片放入对应的文件夹中,图片记得用png格式,记得名字要统一,才能一次性进行配置。

二 配置AndroidManifest.xml

这个文件主要用来配置APP的名称、图标和系统权限,所在的目录在:/android/app/src/main/AndroidManifest.xml

android:label="flutter_app"   //配置APP的名称,支持中文
android:icon="@mipmap/ic_launcher" //APP图标的文件名称

三 生成keystore

keytool -genkey -v -keystore e:/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
image
image

在安卓根目录建立key属性文件,并配置

storePassword=    //输入上一步创建KEY时输入的 密钥库 密码
keyPassword=    //输入上一步创建KEY时输入的 密钥 密码
keyAlias=key
storeFile=    //key.jks的存放路径
image

四 配置android\app\build.gradle

在android{}上面添加如下代码:

def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
image

把下面内容替换

image

替换成:

signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
}
buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}

五 生成APK

运行命令:

flutter build apk

十九 Android打包(AS)

你可能感兴趣的:(flutter框架一文通(一))