乐趣区

flutter笔记1

一.Text

1.TextAlign

// 对齐
child:Text(
  '非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
  textAlign:TextAlign.left,
)

/**
textAlign:TextAlign.left 
*   center: 文本以居中形式对齐, 这个也算比较常用的了。*   left: 左对齐,经常使用,让文本居左进行对齐,效果和 start 一样。*   right : 右对齐,使用频率也不算高。*   start: 以开始位置进行对齐,类似于左对齐。*   end: 以为本结尾处进行对齐,不常用。有点类似右对齐
*/

2.maxLines

设置最多显示的行数,比如我们现在只显示 1 行

child:Text(
  '非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
  textAlign:TextAlign.left,
  maxLines: 1,
)

3.overflow

overflow 属性是用来设置文本溢出时,如何处理

child:Text(
  '非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
  textAlign:TextAlign.left,
  overflow: clip,
)
/*
*  clip:直接切断,剩下的文字就没有了
*  ellipsis: 在后边显示省略号,体验性较好
*  fade: 溢出的部分会进行一个渐变消失的效果
*
*
*/

4.style

style 属性较多

child:Text(
  '非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
  textAlign:TextAlign.left,
  overflow:TextOverflow.ellipsis,
  maxLines: 1,
  style: TextStyle(
    fontSize:25.0,
    color:Color.fromARGB(255, 255, 150, 150),
    decoration:TextDecoration.underline,
    decorationStyle:TextDecorationStyle.solid,
  ),
)
/*
    inherit: true,         // 为 false 的时候不显示
    color: Color.fromARGB(255, 150, 150, 150),                    // 颜色 
    fontSize :22.0,               // 字号
    fontWeight: FontWeight.w700,           // 字重,加粗也用这个字段  FontWeight.w700
    fontStyle: FontStyle.italic ,                // FontStyle.normal  FontStyle.italic 斜体
    letterSpacing: 10.0,        // 字符间距  就是单个字母或者汉字之间的间隔,可以是负数
    wordSpacing: 15.0,        // 字间距 句字之间的间距
    textBaseline: TextBaseline.alphabetic,        // 基线,两个值,字面意思是一个用来排字母的,一人用来排表意字的(类似中文)textBaseline: TextBaseline.ideographic
    height: 1.0,                // 当用来 Text 控件上时,行高(会乘以 fontSize, 所以不以设置过大)decoration: TextDecoration.overline,        // 添加上划线
    decoration: TextDecoration.lineThrough,        // 添加删除线
    decoration: TextDecoration.underline,        // 添加下划线
    decorationColor,    // 划线的颜色
    decorationStyle: TextDecorationStyle.dotted,    // 这个 style 可能控制画实线,虚线,两条线,点, 波浪线等
    debugLabel,
    background:    // 文本背景色
    String fontFamily,    // 字体
    String package,
*/

二.Container 容器组件

Container(容器控件)在 Flutter 是经常使用的控件,它就相当于我们 HTML 里的 <div> 标签

1.padding 属性

padding 的属性就是一个内边距

child:Container(
  child:new Text('Container 容器组件',
        style: TextStyle(fontSize: 40.0)
        ),
  alignment: Alignment.topLeft,
  width:500.0,
  height:400.0,
  color: Colors.lightBlue,
  padding:const EdgeInsets.all(10.0),
)

padding:const EdgeInsets.all(10.0),
设置 Container 的内边距是 10,左右上下全部为 10

padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0)
可以满足我们分别设置上下左右,LTRB 分别代表左、上、右、下


2.margin 属性

child:Container(
  child:new Text('Hello JSPang',
        style: TextStyle(fontSize: 40.0)
        ),
  alignment: Alignment.topLeft,
  width:500.0,
  height:400.0,
  color: Colors.lightBlue,
  padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0),
  margin: const EdgeInsets.all(10.0),
)

3.decoration 属性

decoration 是 container 的修饰器,主要的功能是设置背景和边框
比如你需要给背景加入一个渐变,和边框 这时候需要使用 BoxDecoration 这个类

注意:

需要注意的是如果你设置了 decoration,就不要再设置 color 属性了,因为这样会冲突

child:Container(child:new Text('Hello JSPang',style: TextStyle(fontSize: 40.0),),
  alignment: Alignment.topLeft,
  width:500.0,
  height:400.0,
  padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0),
  margin: const EdgeInsets.all(10.0),
  decoration:new BoxDecoration(
    gradient:const LinearGradient(colors:[Colors.lightBlue,Colors.greenAccent,Colors.purple]
    ),
    border:Border.all(width:2.0,color:Colors.red)
  )
)

三.Image 图片组件的使用

1. 加入图片的几种方式

1.Image.asset: 加载资源图片,就是加载项目资源目录中的图片, 加入图片后会增大打包的包体体积,用的是相对路径。
2.Image.network: 网络资源图片,意思就是你需要加入一段 http://xxxx.xxx 的这样的网络路 …。
3.Image.file: 加载本地图片,就是加载本地文件中的图片,这个是一个绝对路径,跟包体无关。
4.Image.memory: 加载 Uint8List 资源图片

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'Text widget',
        home:Scaffold(
          body:Center(
          child:Container(
            child:new Image.network(
              'http://jspang.com/static/myimg/blogtouxiang.jpg',
              scale:1.0,
            ),
            width:300.0,
            height:200.0,
            color: Colors.lightBlue,
          ),
          ),
        ),
      );
  }
}

2.fit 属性的设置

fit 属性可以控制图片的拉伸和挤压,这些都是根据图片的父级容器来的,我们先来看看这些属性(建议此部分组好看视频理解)。

BoxFit.fill: 全图显示,图片会被拉伸,并充满父容器。
BoxFit.contain: 全图显示,显示原比例,可能会有空隙。
BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。
BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。
BoxFit.fitHeight:高度充满(竖向充满), 显示可能拉伸,可能裁切。
BoxFit.scaleDown:效果和 contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大

 child:Container(
            child:new Image.network(
              'http://img.nodebook.top/nodebooklogo.jpg',
              scale:1.0,
              fit: BoxFit.fill
            ),
            width:300.0,
            height:200.0,
            color: Colors.lightBlue,
            
          )

3. 图片的混合模式

child:new Image.network(
  'http://jspang.com/static/myimg/blogtouxiang.jpg',
    color: Colors.greenAccent,
    colorBlendMode: BlendMode.darken,
)

color:是要混合的颜色,如果你只设置 color 是没有意义的
colorBlendMode: 是混合模式,相当于我们如何混合。


4.repeat 图片重复

ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。

ImageRepeat.repeatX: 横向重复,纵向不重复。

ImageRepeat.repeatY:纵向重复,横向不重复

child:new Image.network(
  'http://jspang.com/static/myimg/blogtouxiang.jpg',
   repeat: ImageRepeat.repeat,
),

四.ListView 列表组件简介

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:'JSPang Flutter Demo',
      home:Scaffold(
        appBar:new AppBar(title:new Text('ListView Widget')
        ),
       body: new ListView(
            children:<Widget>[
                new ListTile(leading:new Icon(Icons.access_time),
                title:new Text('access_time')
                ),
                new ListTile(leading:new Icon(Icons.account_balance),
                title:new Text('account_balance')
                ),
            ]
            )
      ),
    );
  }
}

1. 两行列表

body: new ListView(
  children:<Widget>[
    new ListTile(leading:new Icon(Icons.access_time),
      title:new Text('access_time')
    ),
    new ListTile(leading:new Icon(Icons.account_balance),
      title:new Text('account_balance')
    ),
  ]
),
---

2. 图片

body: new ListView(
  children:<Widget>[
    new Image.network('http://jspang.com/static/upload/20181111/G-wj-ZQuocWlYOHM6MT2Hbh5.jpg'),
    new Image.network('http://jspang.com/static/upload/20181109/1bHNoNGpZjyriCNcvqdKo3s6.jpg'),
    new Image.network('http://jspang.com/static/myimg/typescript_banner.jpg'),
    new Image.network('http://jspang.com/static/myimg/smile-vue.jpg')  
  ]
),

五. 横向列表的使用

其实还是使用我们的 ListView 组件,只是在 ListView 组件里加一个 ScrollDirection 属性。

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'Text widget',
        home:Scaffold(
          body:Center(
          child:Container(
            height:200.0,
            child:new ListView(
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                new Container(
                  width:180.0,
                  color: Colors.lightBlue,
                ), new Container(
                  width:180.0,
                  color: Colors.amber,
                ), new Container(
                  width:180.0,
                  color: Colors.deepOrange,
                ),new Container(
                  width:180.0,
                  color: Colors.deepPurpleAccent,
                ),
              ],
            )
          ),
          ),
        ),
      );
  }
}

1.scrollDirection 属性

ListView 组件的 scrollDirection 属性只有两个值,一个是横向滚动,一个是纵向滚动。默认的就是垂直滚动,所以如果是垂直滚动,我们一般都不进行设置。

Axis.horizontal: 横向滚动或者叫水平方向滚动。

Axis.vertical: 纵向滚动或者叫垂直方向滚动

组件化


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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          body:Center(
          child:Container(
            height:200.0,
            child:MyList()  // => 组件化),
          ),
        ),
      );
  }
}

// MyList
class MyList extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return ListView(
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          new Container(
            width:180.0,
            color: Colors.lightBlue,
          ), new Container(
            width:180.0,
            color: Colors.amber,
          ), new Container(
            width:180.0,
            color: Colors.deepOrange,
          ),new Container(
            width:180.0,
            color: Colors.deepPurpleAccent,
          ),
        ],
    );
  }
}

六. 动态列表的使用

List 类型的使用
List 是 Dart 的集合类型之一, 其实你可以把它简单理解为数组(反正我是这么认为的) , 它的声明有几种方式:

var myList = List(): 非固定长度的声明。
var myList = List(2): 固定长度的声明。
var myList= List<String>(): 固定类型的声明方式。
var myList = [1,2,3]: 对 List 直接赋值。

void main () => runApp(MyApp(items: new List<String>.generate(1000, (i)=> "Item $i")
));

generate 方法传递两个参数,第一个参数是生成的个数,第二个是方法

import 'package:flutter/material.dart';
void main () => runApp(MyApp(items: new List<String>.generate(1000, (i)=> "Item $i")
));

class MyApp extends StatelessWidget{

  final List<String> items;
  MyApp({Key key, @required this.items}):super(key:key);
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          body:new ListView.builder(
            itemCount:items.length,
            itemBuilder:(context,index){
              return new ListTile(title:new Text('${items[index]}'),
              );
            }
          )
        ),
      );
  }
}

七.GridView 网格列表组件

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          body:GridView.count(padding:const EdgeInsets.all(20.0),
            crossAxisSpacing: 10.0,
            crossAxisCount: 3,
            children: <Widget>[const Text('I am Jspang'),
              const Text('I love Web'),
              const Text('jspang.com'),
              const Text('我喜欢玩游戏'),
              const Text('我喜欢看书'),
              const Text('我喜欢吃火锅')
            ],
          )
        ),
      );
  }
}

padding: 表示内边距,这个小伙伴们应该很熟悉。
crossAxisSpacing: 网格间的空当,相当于每个网格之间的间距。

crossAxisCount: 网格的列数,相当于一行放置的网格数量。

2. 加入图片

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          body:GridView(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
              mainAxisSpacing: 2.0,
              crossAxisSpacing: 2.0,
              childAspectRatio: 0.7
            ),
            children: <Widget>[new Image.network('http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/13/093605.61422332_180X260X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/07/092515.55805319_180X260X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/21/090246.16772408_135X190X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/17/162028.94879602_135X190X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/19/165350.52237320_135X190X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/16/115256.24365160_180X260X4.jpg',fit: BoxFit.cover),
             new Image.network('http://img5.mtime.cn/mt/2018/11/20/141608.71613590_135X190X4.jpg',fit: BoxFit.cover),
           
            ],
          )
        ),
      );
  }
}

childAspectRatio: 宽高比,这个值的意思是宽是高的多少倍,如果宽是高的 2 倍,那我们就写 2.0,如果高是宽的 2 倍,我们就写 0.5

一. 水平布局 Row 的使用

Flutter 中的 row 控件就是水平控件,它可以让 Row 里边的子元素进行水平排列
Row 控件可以分为灵活排列和非灵活排列两种

1. 不灵水平布局

从字面上就可以理解到,不灵活就是根据 Row 子元素的大小,进行布局。如果子元素不足,它会留有空隙,如果子元素超出,它会警告。


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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
      
        home:Scaffold(
          appBar:new AppBar(title:new Text('水平方向布局'),
          ),
          body:new Row(
            children: <Widget>[
              new RaisedButton(onPressed: (){ },
                color:Colors.redAccent,
                child:new Text('红色按钮')
              ),
              new RaisedButton(onPressed: (){ },
                color:Colors.orangeAccent,
                child: new Text('黄色按钮'),
              ),  
              new RaisedButton(onPressed: (){ },
                color:Colors.pinkAccent,
                child:new Text('粉色按钮')
              )
            ],
          )
        ),
      );
  }
}

这时候你会发现的页面已经有了三个按钮,但这三个按钮并没有充满一行,而是出现了空隙。这就是不灵活横向排列造成的。它根据子元素的大小来进行排列。如果我们想实现充满一行的效果,就要使用灵活水平布局了


2. 灵活水平布局

在按钮的外边加入 Expanded 就可以了

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
      
        home:Scaffold(
          appBar:new AppBar(title:new Text('水平方向布局'),
          ),
          body:new Row(
            children: <Widget>[
              Expanded(child:new RaisedButton(onPressed: (){ },
                color:Colors.redAccent,
                child:new Text('红色按钮')
              )),
              Expanded(child:new RaisedButton(onPressed: (){ },
                  color:Colors.orangeAccent,
                  child: new Text('黄色按钮'),
                )
              
              ),
              Expanded(child:new RaisedButton(onPressed: (){ },
                color:Colors.pinkAccent,
                child:new Text('粉色按钮')
              )             
              )
            ],
          )
        ),
      );
  }
}


3. 灵活和不灵活的混用

中间的按钮大,而两边的按钮保持真实大小

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
      
        home:Scaffold(
          appBar:new AppBar(title:new Text('水平方向布局'),
          ),
          body:new Row(
            children: <Widget>[
             new RaisedButton(onPressed: (){ },
                color:Colors.redAccent,
                child:new Text('红色按钮')
            ),
            Expanded(child:new RaisedButton(onPressed: (){ },
                  color:Colors.orangeAccent,
                  child: new Text('黄色按钮'),
                )
              
              ),
            new RaisedButton(onPressed: (){ },
                color:Colors.pinkAccent,
                child:new Text('粉色按钮')
              )
            ],
          )
        ),
      );
  }
}

二. 垂直布局 Column 组件

1. 三行文字布局

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
      
        home:Scaffold(
          appBar:new AppBar(title:new Text('垂直方向布局'),
          ),
          body:Column(
            children: <Widget>[Text('I am JSPang'),
             Text('my website is jspang.com'),
             Text('I love coding')
            ],
            crossAxisAlignment: CrossAxisAlignment.start
          )
        ),
      );
  }
}

CrossAxisAlignment.star:居左对齐。
CrossAxisAlignment.end:居右对齐。

CrossAxisAlignment.center:居中对齐。

2. 主轴和副轴的辨识

mainAxisAlignment 主轴的对齐方式

main 轴:如果你用 column 组件,那垂直就是主轴,如果你用 Row 组件,那水平就是主轴。

cross 轴:cross 轴我们称为幅轴,是和主轴垂直的方向。比如 Row 组件,那垂直就是幅轴,Column 组件的幅轴就是水平方向的

1. 垂直居中

mainAxisAlignment: MainAxisAlignment.center


3. 水平方向相对屏幕居中

让文字相对于水平方向居中,我们如何处理?其实只要加入 Center 组件就可以轻松解决

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      return MaterialApp(
        title:'ListView widget',
        
        home:Scaffold(
          appBar:new AppBar(title:new Text('垂直方向布局'),
          ),
          body:Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[Center(child:Text('I am JSPang')),
             Center(child:Text('my website is jspang.com')),
             Center(child:Text('I love coding'))
            ],
          )
        ),
      );
  }
}

4.Expanded 属性的使用

在学习水平布局的时候我们对 Expanded 有了深刻的理解,它就是灵活布局。比如我们想让中间区域变大,而头部区域和底部根据文字所占空间进行显示

body:Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[Center(child:Text('I am JSPang')),
    Expanded(child:Center(child:Text('my website is jspang.com'))),
    Center(child:Text('I love coding'))
  ],
)

三.Stack 层叠布局

1. 层叠布局的 alignment 属性

alignment 属性是控制层叠的位置的,建议在两个内容进行层叠时使用。它有两个值 X 轴距离和 Y 轴距离,值是从 0 到 1 的,都是从上层容器的左上角开始算起的

2.CircleAvatar 组件的使用

CircleAvatar 这个经常用来作头像的,组件里边有个 radius 的值可以设置图片的弧度

new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
  radius: 100.0,
)

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      var stack = new Stack(alignment: const FractionalOffset(0, 0.1),
        children: <Widget>[
          new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
            radius: 100.0,
          ),
          new Container(
            decoration: new BoxDecoration(color: Colors.lightBlue,),
            padding: EdgeInsets.all(5.0),
            child: new Text('JSPang 技术胖'),
          )
        ],
      );


      return MaterialApp(
        title:'ListView widget',
        
        home:Scaffold(
          appBar:new AppBar(title:new Text('垂直方向布局'),
          ),
          body:Center(child:stack),
        ),
      );
  }
}

四.Stack 的 Positioned 属性

如果是超过两个组件的层叠该如何进行定位那? 这就是我们加今天要学的主角 Positioned 组件了。这个组件也叫做层叠定位组件

Positioned 组件的属性
bottom: 距离层叠组件下边的距离
left:距离层叠组件左边的距离
top:距离层叠组件上边的距离
right:距离层叠组件右边的距离
width: 层叠定位组件的宽度
height: 层叠定位组件的高度

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      var stack = new Stack(
        
        children: <Widget>[
          new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
            radius: 100.0,
          ),
          new Positioned(
            top:10.0,
            left:10.0,
            child: new Text('JSPang.com'),
          ),
          new Positioned(
            bottom:10.0,
            right:10.0,
            child: new Text('技术胖'),
          )
        ],
      );


      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          appBar:new AppBar(title:new Text('层叠布局'),
          ),
          body:Center(child:stack),
        ),
      );
  }
}

五. 卡片组件布局

Flutter 还有一种比较比较酷炫的布局方式: 卡片式布局。这种布局类似 ViewList,但是列表会以物理卡片的形态进行展示

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
      var card = new Card(
         child: Column(
           children: <Widget>[
             ListTile(title:new Text('吉林省吉林市昌邑区',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('技术胖:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),
              ListTile(title:new Text('北京市海淀区中国科技大学',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('胜宏宇:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),
              ListTile(title:new Text('河南省濮阳市百姓办公楼',style: TextStyle(fontWeight: FontWeight.w500),),
               subtitle: new Text('JSPang:1513938888'),
               leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
             ),
             new Divider(),],
         ),
      
      );


      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          appBar:new AppBar(title:new Text('卡片布局'),
          ),
          body:Center(child:card),
        ),
      );
  }
}

一般导航组件

1.RaisedButtom 按钮组件

它有两个最基本的属性:

child:可以放入容器,图标,文字。让你构建多彩的按钮。onPressed:点击事件的相应,一般会调用 Navigator 组件

我们在作页面导航时,大量的使用了 RaisedButton 组件,这个组件的使用在实际工作中用的也比较多

2.Navigator.push 和 Navigator.pop

1.Navigator.push:是跳转到下一个页面,它要接受两个参数一个是上下文 context,另一个是要跳转

2.Navigator.pop:是返回到上一个页面,使用时传递一个 context(上下文)参数,使用时要注意的是,你必须是有上级页面的,也就是说上级页面使用了 Navigator.push。

import 'package:flutter/material.dart';

void main(){
  runApp(MaterialApp(
    title:'导航演示 1',
    home:new MyApp()));
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return new Scaffold(appBar: AppBar(title:Text('导航页面')),
      body:Center(
        child:RaisedButton(child:Text('查看商品详情页面'),
          onPressed: (){
            Navigator.push(context,new  MaterialPageRoute(builder:(context) =>new SecondScreen())
            );
          },
        )
      )
    );
  }
}

class SecondScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Scaffold(appBar:AppBar(title:Text('技术胖商品详情页')),
      body:Center(
        child:RaisedButton(child:Text('返回'),
          onPressed: (){Navigator.pop(context);
          },
      ))
    );

  }
}
# Center 组件

import ‘package:flutter/material.dart’;

void main(){

runApp(new Center(  //Center 组件
    child: Text(
        "文本内容",
        textDirection: TextDirection.ltr
    )
))

}

# 自定义组件

StatelessWidget // 无状态组件
StatefulWidget // 有状态组件

class MyApp extends StatelessWidget{

@override
Widget build(BuildContext context) {
    return Center(  //Center 组件
        child: Text(
            "文本内容",
            textDirection: TextDirection.ltr,
            style: TextStyle(
                fontSize: 40.0,
                color: Color.fromRGBO(255,0,0,0.5)
            )
        )
    )
}

}

# MaterialApp 和 Scaffold  
> MaterialApp 是一个方便的 Widget, 它封装了应用程序实现 Material Desigin 所需要的一些 Widget 一般作为顶层 Widget 组件

### 常用属性
home(主页)
title(标题)
color(颜色)
theme(主题)
routes(路由)

### Scaffold 组件
> Scaffold 是 Material Desigin 布局结构的基本实现

### Scaffold 组件属性
appBar 显示在界面顶部的一个 appBar
body 当前界面所显示的主要 内饰  Widget
drawer 抽屉菜单控件

import ‘package:flutter/material.dart’;

void main(){
runApp(MaterialApp(

title:'导航演示 1',
home:new MyApp(),
theme:ThemeData(primarySwatch: Colors.yellow)

));
}

class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){

return new Scaffold(appBar: AppBar(title:Text('导航页面')),
  body:Center(
    child:RaisedButton(child:Text('查看商品详情页面'),
      onPressed: (){
        Navigator.push(context,new  MaterialPageRoute(builder:(context) =>new SecondScreen())
        );
      },
    )
  )
);

}
}

class SecondScreen extends StatelessWidget{
@override
Widget build(BuildContext context){

return Scaffold(appBar:AppBar(title:Text('技术胖商品详情页')),
  body:Center(
    child:RaisedButton(child:Text('返回'),
      onPressed: (){Navigator.pop(context);
      },
  ))
);

}
}

退出移动版