# flutter 学习笔记 # 组件的使用 * Text文字组件 * `textAlign: TextAlign.start,` // 文本对齐方式 * `textDirection: TextDirection.ltr` // 文本方向 * `maxLines:1` // 最大行数 * `textScaleFactor: 1.5,` // 文字缩放 * `overflow: TextOverflow.ellipsis,` // 超出处理 * `style:` * TextStyle组件 ```dart TextStyle( color: Colors.blue, fontSize: 18.0, height: 1.2, fontFamily: "Courier", background: new Paint()..color=Colors.yellow, decoration:TextDecoration.underline, decorationStyle: TextDecorationStyle.dashed ), ``` * 文本接合,多个textSpan对文本进行修饰,然后拼合在一起 ```dart Text.rich(TextSpan( children: [ TextSpan( text: "https://flutterchina.club", style: TextStyle( color: Colors.blue ), recognizer: _tapRecognizer ), ... ] )) ``` * 字体设置[链接]('https://book.flutterchina.club/chapter3/text.html') * 按钮 * `RaisedButton` // 悬浮按钮 * `FlatButton` // 扁平按钮 * `OutlineButton` // 默认有边框 * `IconButton` // 可点击的icon * `icon: Icon(Icons.thumb_up),` * 前三个都可以加`.icon`然后属性变成`icon`和`label` * 自定义 ```dart const FlatButton({ ... @required this.onPressed, //按钮点击回调 this.textColor, //按钮文字颜色 this.disabledTextColor, //按钮禁用时的文字颜色 this.color, //按钮背景颜色 this.disabledColor,//按钮禁用时的背景颜色 this.highlightColor, //按钮按下时的背景颜色 this.splashColor, //点击时,水波动画中水波的颜色 this.colorBrightness,//按钮主题,默认是浅色主题 this.padding, //按钮的填充 this.shape, //外形 @required this.child, //按钮的内容 }) ``` * 图片 * pubspec.yaml配置 ```yaml assets: - images/avatar.png ``` * 加载图片 ```dart Image( image: AssetImage("images/avatar.png"), width: 100.0 ); Image.asset("images/avatar.png", width: 100.0, ) Image( image: NetworkImage( "https://avatars2.githubusercontent.com/u/20411648?s=460&v=4"), width: 100.0, ) Image.network( "https://avatars2.githubusercontent.com/u/20411648?s=460&v=4", width: 100.0, ) const Image({ ... this.width, //图片的宽 this.height, //图片高度 this.color, //图片的混合色值 this.colorBlendMode, //混合模式 this.fit,//缩放模式 this.alignment = Alignment.center, //对齐方式 this.repeat = ImageRepeat.noRepeat, //重复方式 ... }) ``` * ICON * `Icon(Icons.accessible,color: Colors.green,),` * 使用自定义字体图标[链接]('https://book.flutterchina.club/chapter3/img_and_icon.html') * Switch开关组件 * `value: true` * `onChanged` * Checkbox多选组件 * `value: true` * `onChanged` * Stack层叠组件 * 定位相对于父元素 * `alignment: Alignment.center` // 总体控制 * `alignment: Alignment(0,0)` // float(-1~1) 0,0居中 * `children: []` * Align组件 * `alignment: Alignment.center` // 单独控制 * `alignment: Alignment(0,0)` // float(-1~1) 0,0居中 * `child: ` // 需要定位的子组件 * Positioned组件 * `left, bottom, top, right` // int 默认为0 * `child: ` // 需要定位的子组件image * AspectRatio组件 * 默认横向占满父组件 * 可以用来控制图片 * `aspectTatio: 2.0/1.0` // 宽高比 * `child: ` // 子组件 * Card组件 * `margin: EdgeInsets.all(10)` // 外边距 * `child: ` // 子组件 * ClipOval组件 * 可以用来裁剪原型头像 * `child: ` // 子组件 * CircleAvatar组件 * 感觉可以自适应头像大小 * `backgroungImage: NetworkImage('src')` * RaisedButton组件 * `child:` // 子组件 * `textColor: Theme.of(context).accentColor,` // 文字颜色 * `textColor: Colors.red,` // 文字颜色 * `onPressed: (){}` // 点击事件 * Warp组件 * 相对于父组件横向占满 * 可以自动换行 * `spacing: 10,` // 元素和元素之间的距离 * `runSpacing: 10` // 元素在纵轴之间的距离 * `alignment: WarpAlignment.srart` // 水平对齐方式 * `runAlignment: WarpAlignment.spaceAround` // 纵向对齐方式 * `direction: Axis.vertical` // 纵向排列 * SizedBox组件 * `height: 30,` * `width:10,` * 空白盒子 * StatefullWidget * `setState((){})` 修改需要刷新的内容,类似小程序的setData * Scaffold组件 * appBar组件 * `title: Text('text')` // 标题 * `backgroundColor: Colors.red` // 背景颜色 * `leading: IconButton(icon: Icon(Icons.menu), onPressed:(){})` // 左边加东西 * `actions: []` // 右边加东西 * `centerTitle: true` // 不论是不是ios都给居中显示 * 菜单栏 ```dart DefaultTabController( length : 2, // tab的个数 child: Scafford( appBar: AppBar( title: Text('title'), bottom: TabBar( tabs: [ Tab(text:'1'), Tab(text:'2'), Tab(text:'3'), ] ) ), body: TabBarView( children: [ Text('text1'), Text('text2'), Text('text3'), ] ) ) ) ``` * TabBar组件 * `indicatorColor: Colors.red,` * `isScrollable: true` // 允许滑动 * `tabs: []` * Tab组件 * `text:"text"` * TabBarView组件 * `children: []` * body * bottomNavigationBar组件 * `currentIndex: 0,` // 当前选中的tab * `onTap: (int index){}` // 点击事件,默认参数是点击了第几个按钮 * `items: []` // 按钮内容 * BottomNavigationBarItem组件 * `icon: Icon(Icons.home),` // 图标 * `title: Text('主页')` // 文字 * floatingActionButton浮动按钮组件 * child: * onPressed: (){} * Navigator路由跳转组件 ```dart // 路由跳转 Navigator.of(context).push( MaterialPageRoute( builder: (context)=> FormPage(参数) ) ) // 返回上一界面 Navigator.of(context).pop() // 替换掉当前界面 Navigator.of(context).pushReplacementNamed('/home') // 重置路由 Navigator.of(context).pushAndRemoveUntil( new MaterialPageRoute( builder: (context) => new Tabs(index: 1), ), (route) => route == null ) ``` * MaterialPageRoute * `WidgetBuilder builder` // 是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容,返回值是一个widget。我们通常要实现此回调,返回新路由的实例。 * `RouteSettings settings` // 包含路由的配置信息,如路由名称、是否初始路由(首页)。 * `bool maintainState = true,` // 默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false。 * `bool fullscreenDialog = false,` // 表示新的路由页面是否是一个全屏的模态对话框,在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)。 * MaterialApp * `debugShowCheckedModeBanner: false` // 去除斜着的debug标识 * routes ```dart routes: { '/form': (context) => FromPage(), '/search': (context) => SearchPage(), } Navigator.pushNamed(context, '/search') // 在跳转到的路由的build方法里写 var args=ModalRoute.of(context).settings.arguments; // 就可以传输参数了 Naviagtor.pushNamed(context, '/search', arguments:{"id": 123}); // 或者是定义路由的时候进行传参,这样就可以正常的使用了 routes: { "tip2": (context){ return TipRoute(text: ModalRoute.of(context).settings.arguments); }, }, ``` * `initialRoute: '/'` // 初始化加载的路由 * 对于路由的固定写法 ```dart // Route.dart import 'package:flutter/material.dart'; import '../pages/Tabs.dart'; import '../pages/Search.dart'; import '../pages/Form.dart'; final Map routes = { '/':(contxt,{arguments})=>Tabs(), '/search':(contxt,{arguments}) =>SearchPage(arguments: arguments), '/form': (context,{arguments}) =>FormPage(arguments: arguments), }; // 这个东西实际上是一个路由生成钩子,只有在没有找到指定路由的时候才会被调用,当前没有设置route所有的路由都会经过这个钩子进行处理,这里也可以当成路由守卫,判断各种权限然后进行路由的导航 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; } } }; // main.dart import 'package:flutter/material.dart'; import 'routes/Routes.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( // home:Tabs(), initialRoute: '/', onGenerateRoute: onGenerateRoute ); } } // 路由跳转 Naviagtor.pushNamed(context, '/search', arguments:{"id": 123}); ``` * 资源管理 `pubspec.yaml` ```yaml flutter: assets: - assets/my_icon.png - assets/background.png ``` assets指定应包含在应用程序中的文件, 每个asset都通过相对于pubspec.yaml文件所在的文件系统路径来标识自身的路径。asset的声明顺序是无关紧要的,asset的实际目录可以是任意文件夹(在本示例中是assets文件夹) * 在Widget树中获取State对象 * 方法一 ```dart // 直接通过of静态方法来获取ScaffoldState ScaffoldState _state=Scaffold.of(context); _state.showSnackBar( SnackBar( content: Text("我是SnackBar"), ), ); ``` * 方法二 ```dart //定义一个globalKey, 由于GlobalKey要保持全局唯一性,我们使用静态变量存储 static GlobalKey _globalKey= GlobalKey(); ... Scaffold( key: _globalKey , //设置key ... ) _globalKey.currentState.openDrawer() ``` GlobalKey是Flutter提供的一种在整个APP中引用element的机制。如果一个widget设置了GlobalKey,那么我们便可以通过globalKey.currentWidget获得该widget对象、globalKey.currentElement来获得widget对应的element对象,如果当前widget是StatefulWidget,则可以通过globalKey.currentState来获得该widget对应的state对象。 *