Flutter从零到∞学习笔记
有状态widget:StatefulWidget和无状态widget:StatelessWidget 前者不需要实现Widget build(BuildContext context)。
具体的选择取决于widget是否需要管理一些状态
在Dart语言中使用下划线前缀标识符,会强制其变成私有的。
Icons.favorite Icons类里面有很多默认图标
isOdd 是否奇数 2.isOdd -> false 1.isOdd -> true
pushSaved “”开头的自动转成私有(方法和变量)
导航栏添加按钮和事件
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Startup Name Generator'),
actions: <Widget>[
// AppBar 添加一个按钮 样式为list 事件是_pushSaved
new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved)
],
),
body: _buildSuggestions(),
);
}
// tooltip 长时间按下的提示文字
IconButton(icon: new Icon(Icons.search), tooltip: 'Search', onPressed: null)
- 界面跳转方法
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
},
),
);
- 一行函数写法
// 多行
void main() {
runApp(
new Center(
child: new Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
)
)
}
// 一行
void main() => runApp(new MyApp());
// Material 是UI呈现的“一张纸”
请确保在pubspec.yaml文件中,将flutter的值设置为:uses-material-design: true。这允许我们可以使用一组预定义Material icons。
Row(横向排列)和Column(纵向排列)
child: new Row(
children: <Widget>[
new ...,
new ...,
new ...,
],
)
child: new Column(
children: <Widget>[
new ...,
new ...,
new ...,
],
),
cached_network_image 图片占位和淡入淡出
push
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new 新界面),
);
// 如果需要传值:
新界面({Key key, @required this.接收字段的名字}) : super(key: key);
pop
Navigator.pop(context);
import 'dart:convert'; // package将响应内容转化为一个json Map
// 使用fromJson工厂函数,将json Map 转化为一个Post对象
new Post.fromJson(json);
future参数是一个异步的网络请求
import 'dart:io'; // 添加请求的headers
// 长连接
import 'package:web_socket_channel/io.dart'; import 'package:multi_server_socket/multi_server_socket.dart';
- // 网络请求
Future<Post> fetchPost() async {
final response = await http.get('[http://jsonplaceholder.typicode.com/posts/1](http://jsonplaceholder.typicode.com/posts/1)');
final responseJson = json.decode(response.body);
return new Post.fromJson(responseJson);
}
// 请求添加headers
/*
Future<Post> fetchPost() async {
final response = await http.get(
'[https://jsonplaceholder.typicode.com/posts/1](https://jsonplaceholder.typicode.com/posts/1)',
headers: {HttpHeaders.AUTHORIZATION: "Basic your_api_token_here"},
);
final json = jsonDecode(response.body);
return new Post.fromJson(json);
}
*/
new FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
return new CircularProgressIndicator();
}
)
- 长连接
// 连接长连接
IOWebSocketChannel.connect('[ws://echo](ws://echo/).[websocket.org](http://websocket.org/)’)
// 接收消息
new StreamBuilder(
stream: widget.channel.stream,
builder: (context, snapshot) {
return new Padding(
child: new Text(snapshot.hasData ? '${snapshot.data}' : ''),
padding: const EdgeInsets.symmetric(vertical: 20.0)
);
}
)
// 发送消息
widget.channel.sink.add(_textController.text);
// 关闭长连接
widget.channel.sink.close();
- 在Flutter中添加资源和图片
https://flutterchina.club/assets-and-images/
- 标准widget:
Container 添加 padding, margins, borders, background color, 或将其他装饰添加到widget. GridView 将 widgets 排列为可滚动的网格. ListView 将widget排列为可滚动列表 Stack 将widget重叠在另一个widget之上. Material Components: Card 将相关内容放到带圆角和投影的盒子中。 ListTile 将最多3行文字,以及可选的行前和和行尾的图标排成一行
- pubspec.yaml中添加字体 注意缩进对齐 注意缩进对齐 注意缩进对齐
-asset 路径是与pubspec.yaml平级的文件路径
flutter:
# Include the Material Design fonts.
uses-material-design: true
fonts:
- family: Rock Salt
fonts:
# [https://fonts.google.com/specimen/Rock+Salt](https://fonts.google.com/specimen/Rock+Salt)
- asset: fonts/Arial-Unicode.ttf
- family: VT323
fonts:
# [https://fonts.google.com/specimen/VT323](https://fonts.google.com/specimen/VT323)
- asset: fonts/Arial-Unicode.ttf
- family: Ewert
fonts:
# [https://fonts.google.com/specimen/Ewert](https://fonts.google.com/specimen/Ewert)
- asset: fonts/Ewert-Regular.ttf
- 比如一个关闭按钮在
new Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
new FlatButton(onPressed: () {
}, child: Icon(Icons.close))
],);
- 分割线
new Divider(color: Colors.lightBlue,)
- 自定义Icon
new Image.asset(“图片路径", width: 20.0, height: 20.0,)
- 按钮宽高
001、
new Padding(padding: new EdgeInsets.fromLTRB(48.0, 20.0, 48.0, 20.0),
child: new Row(
children: <Widget>[
new Expanded(child:
new RaisedButton(onPressed: (){
},
//设置控件的高度
child: new Padding(padding: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: new Text("登录",
style: TextStyle(color: Colors.white)
),
),
color: Colors.brown,
),
),
],
),
),
002、
new Container(
width: MediaQuery.of(context).size.width - 48 * 2 ,
padding: new EdgeInsets.only(top: 40.0),
child: new RaisedButton(onPressed: (){
},
//设置控件的高度
child: new Padding(padding: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: new Text("登录",
style: TextStyle(color: Colors.white)
),
),
color: Colors.brown,
),
),
003、
Widget _bigButton(String text, double lSpace, double rSpace) {
return new Container(
width: MediaQuery.of(context).size.width - lSpace - rSpace,
height: 48.0,
margin: new EdgeInsets.only(left: lSpace, right: rSpace),
color: Colors.white54,
padding: new EdgeInsets.only(top: 0.0),
child: new RaisedButton(onPressed: (){
print(text);
},
child: new Padding(padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: new Text(text,
style: TextStyle(color: Colors.white)
),
),
color: Colors.brown,
),
);
}
- 设备尺寸
MediaQuery.of(context).size.width
- 设备像素密度
MediaQuery.of(context).devicePixelRatio
- 状态栏高度
MediaQuery.of(context).padding.top
担心键盘挡住控件,可以使用 SingleChildScrollView,将SingleChildScrollView当做容器。
一个超级简单界面
import 'package:flutter/material.dart';
class RegisterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.black,
body: new RegisterWidget(),
);
}
}
class RegisterWidget extends StatefulWidget {
RegisterWidgetState createState() => RegisterWidgetState();
}
class RegisterWidgetState extends State<RegisterWidget> {
@override
Widget build(BuildContext context) {
return new Text("RegisterPage", style: TextStyle(color: Colors.white),);
}
}
- Flutter 按钮总结
· InkWell // 纯文字按钮 · OutLineButton // 边框按钮 · IconButton // icon按钮 ·
- import 'package:flutter/services.dart';
TextField inputFormatters: <TextInputFormatter> [ WhitelistingTextInputFormatter.digitsOnly, ],
37 . 验证码按钮
new Positioned(
child: new Container(
width: 80.0,
height: 27.0,
alignment: Alignment.center,
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.white,
width: 1.0,
),
borderRadius: new BorderRadius.circular(4.0),
),
child: InkWell(
child: _mText(_verifyStr, 12.0),
onTap: () {
},
),
)
),
- 倒计时方法
@override
void dispose() {
super.dispose();
_cancelTimer();
}
_startTimer() {
if (_verifyStr == '重新发送' || _verifyStr == '获取验证码') {
_seconds = 5;
_timer = new Timer.periodic(new Duration(seconds: 1), (timer) {
if (_seconds == 0) {
_cancelTimer();
return;
}
_seconds--;
_verifyStr = '$_seconds(s)';
setState(() {});
if (_seconds == 0) {
_verifyStr = '重新发送';
}
});
}
}
_cancelTimer() {
_timer?.cancel();
}
- 富文本拼接: 协议
Widget _protocolWidget() {
return new Container(
child: new Row(
children: <Widget>[
new GestureDetector(
onTap: () {
print("选择");
},
child: Icon(Icons.add_alert, color: Colors.white),
),
new Text.rich(
new TextSpan(
text: '我已阅读并同意',
style: new TextStyle(
fontSize: 12.0,
color: Colors.grey[500],
fontWeight: FontWeight.w400,
),
children: [
new TextSpan(
recognizer: new TapGestureRecognizer()
..onTap = () {
print("《燎原用户服务协议》");
},
text: "《燎原用户服务协议》",
style: new TextStyle(
fontSize: 14.0,
color: Color(0XFFB57A36),
fontWeight: FontWeight.w400,
),
)
]
)
),
],
)
);
}
- 阴影、圆角
new Card(
elevation: 4.0,
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0),
bottomLeft: Radius.circular(12.0),
bottomRight: Radius.circular(2.0),
)
),
child: new IconButton(icon: Icon(Icons.add), onPressed: () {
}),
)
- YYTabbarWidget
import 'package:flutter/material.dart';
// with AutomaticKeepAliveClientMixin
class YYTabbarWidget extends StatefulWidget {
List<Widget> tabItems = [];
Widget title;
List<Widget> tabViews = [];
PageController pageController;
final ValueChanged<int> onPageChanged;
final Widget drawer;
YYTabbarWidget({Key key,
this.drawer,
this.tabItems,
this.title,
this.tabViews,
this.pageController,
this.onPageChanged,
}) : super(key: key);
_YYTabbarWidgetState createState() => _YYTabbarWidgetState(drawer, title, tabItems, tabViews, pageController, onPageChanged);
}
class _YYTabbarWidgetState extends State<YYTabbarWidget> with SingleTickerProviderStateMixin {
final Widget _title;
final List<Widget> _tabViews;
final List<Widget> _tabItems;
final ValueChanged<int> _onPageChanged;
final Widget _drawer;
_YYTabbarWidgetState(
this._drawer,
this._title,
this._tabItems,
this._tabViews,
this._pageController,
this._onPageChanged,
) : super();
TabController _tabController;
PageController _pageController;
@override
void initState() {
super.initState();
_tabController = new TabController(length: _tabItems.length, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
_renderTab() {
print(_tabItems);
List<Widget> list = new List();
for (int i = 0; i < _tabItems.length; i++) {
list.add(new FlatButton(onPressed: () {
print(i);
_pageController.jumpTo(MediaQuery
.of(context)
.size
.width * i);
}, child: _tabItems[I],
)
);
}
return list;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
drawer: _drawer,
appBar: new AppBar(
title: _title,
),
body: new PageView(
controller: _pageController,
children: _tabViews,
onPageChanged: (index) {
_tabController.animateTo(index);
_onPageChanged?.call(index);
},
),
bottomNavigationBar: new Material(
color: Colors.white,
child: new TabBar(
indicatorPadding: new EdgeInsets.only(top: 0.0),
controller: _tabController,
tabs: _renderTab(),
indicatorColor: Colors.red,
),
),
);
}
}
- ListView 添加刷新,当数量少的时候不能滚动
physics: new AlwaysScrollableScrollPhysics(), // 让ListView一直可以滚动
- tabView切换 子界面都会调用initState
解决:AutomaticKeepAliveClientMixin
class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
}
- 路有跳转
///不带参数的路由表跳转
Navigator.pushNamed(context,routeName);
///跳转新页面并且替换,比如登录页跳转主页
Navigator.pushReplacementNamed(context,routeName);
///跳转到新的路由,并且关闭给定路由的之前的所有页面
Navigator.pushNamedAndRemoveUntil(context,'/calendar',ModalRoute.withName('/'));
///带参数的路由跳转,并且监听返回
Navigator.push(context,newMaterialPageRoute(builder:(context)=>newNotifyPage())).then((res){
///获取返回处理
});
- flutter lib
cupertino_icons: ^0.1.2 #icon flutter_spinkit: "^2.1.0" # load more loading import 'package:flutter_spinkit/flutter_spinkit.dart'; dio: x.x.x #无网络请求 import 'package:dio/dio.dart';
- dio网络请求示例
_dioRequest() async {
Dio dio = new Dio();
Response response;
try {
String url;
var params; // 请求参数
Options options; // 配置:超时,请求头,请求类型等
response = await dio.request(url, data: params, options: options);
} on DioError catch(e) {
// 请求出错时,返回一个DioError对象
}
}
- build_runner的使用
1、在根目录运行 2、一次性创建.g.dart文件 使用build 此时目录内不能有.g.dart文件 3、watch是监听 有model类的文件创建 自动创建.g.dart文件 flutter packages pub run build_runner build flutter packages pub run build_runner watch
Flutter从零到∞学习笔记的更多相关文章
- CSS零基础学习笔记.
酸菜记 之 CSS的零基础. 这篇是我自己从零基础学习CSS的笔记加理解总结归纳的,如有不对的地方,请留言指教, 学前了解: CSS中字母是不分大小写的; CSS文件可以使用在各种程序文件中(如:PH ...
- Spark (Python版) 零基础学习笔记(一)—— 快速入门
由于Scala才刚刚开始学习,还是对python更为熟悉,因此在这记录一下自己的学习过程,主要内容来自于spark的官方帮助文档,这一节的地址为: http://spark.apache.org/do ...
- Spark (Python版) 零基础学习笔记(二)—— Spark Transformations总结及举例
1. map(func) 将func函数作用到数据集的每个元素,生成一个新的分布式的数据集并返回 >>> a = sc.parallelize(('a', 'b', 'c')) &g ...
- Flutter学习笔记(1)--环境安装
flutter最近显得格外的火,公司的同事也一直在谈论flutter,感觉自己不学学就要失业了...所以决定顺应潮流学习以下flutter,做一下学习笔记,希望可以给需要的同学带来一些帮助~ 正文为f ...
- 《零基础学JavaScript(全彩版)》学习笔记
<零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
- Flutter学习笔记(3)--Dart变量与基本数据类型
一.变量 在Dart里面,变量的声明使用var.Object或Dynamic关键字,如下所示: var name = ‘张三’: 在Dart语言里一切皆为对象,所以如果没有将变量初始化,那么它的默认值 ...
- Flutter学习笔记(4)--Dart函数
如需转载,请注明出处:Flutter学习笔记(4)--Dart函数 Dart是一个面向对象的语言,所以函数也是对象,函数属于Function对象,函数可以像参数一样传递给其他函数,这样便于做回调处理: ...
- Flutter学习笔记(5)--Dart运算符
如需转载,请注明出处:Flutter学习笔记(5)--Dart运算符 先给出一个Dart运算符表,接下来在逐个解释和使用.如下: 描述 ...
随机推荐
- 异常处理与MiniDump 用于投放市场c++异常捕获
最近一段时间,新上线的软件在外场偶尔会出现异常崩溃的情况.由于试用范围比较分散,很难一一前往现场定位问题.而传统的log日志方法,在崩溃的情况下,并不能比较准确的表示出问题位置,这使得软件调试进程缓慢 ...
- [转]50个极好的bootstrap 后台框架主题下载
50个极好的bootstrap 后台框架主题下载 http://sudasuta.com/bootstrap-admin-templates.html 越来越多的设计师和前端工程师开始用bootstr ...
- 发送消息-配置app_id
$user_id = $curr_workitem["creater_id"]; $user_name = g('dao_user') -> get_by_id($user_ ...
- x86指令格式
学习于逆向工程核心原理IA-32指令章节 格式 x86指令格式 指令前缀 出现特定操作码时用作补充说明,图中的冒号前的64就是指令前缀 操作码 实际的指令,如图中的FF.89.80都是操作码 Mod ...
- git push fatal: The remote end hung up unexpectedly
git push fatal: The remote end hung up unexpectedly git config http.postBuffer git gc --aggressive 不 ...
- meta标签大全(荐)
html的meta总结(常用) 1.Meta标签大全 <!-- 声明文档使用的字符编码 --> <meta charset='utf-8'> <!-- 优先使用 IE 最 ...
- PHP合并数组及去重
本文介绍的是一维数组的去重 合并数组的方法 array_merge: 数字键,直接往后添加,key重置 字符串键,后面的数组的值会替代前面的值 +: 数字键,后面的数组的值不会替代前面的值 字符串键, ...
- 嵌入式常用技术概览之SPI
一.先决知识 (1)理解并知道移位寄存器如何工作 二.SPI概述 SPI(serial Peripheral Interface 串行片上(外围)设备接 ...
- select()函数 的学习
select()的介绍 全是拷贝的如下文章: https://www.cnblogs.com/wenqiang/p/5508541.html select()函数的用例代码摘录如下文章: https: ...
- DOS的重定向命令及在安全方面的应用
dos的重定向命令 2006-10-15 16:47 新手DOS应用技巧人小鬼大 重定向命令在安全方面的应用来源:ChinaITLab收集整理2005-7-21 11:12:00 大家知道,DOS下有 ...