赞
踩
Flutter从入门到实战
一共分为23个系列
①(Flutter、Dart环境搭建篇) 共3个内容 已更新
②(Dart语法1 篇) 共4个内容 已更新
③(Dart语法2 篇) 共2个内容 已更新
④(Flutter案例开发篇) 共4个内容 已更新
⑤(Flutter的StatelessWidget 共3个内容 已更新
⑥(Flutter的基础Widget篇) 共2个内容 已更新
⑦(布局Widget篇) 共1个内容 已更新
⑧(Flex、Row、Column以及Flexible、Stack篇) 共1个内容 已更新
⑨(滚动的Widget篇) 共4个内容 已更新
⑩(Dart的Future和网络篇) 共3个内容 已更新
⑪(豆瓣案例-1篇) 共3个内容 已更新
⑫(豆瓣案例-2篇) 共3个内容 已更新
官方文档说明
官方视频教程
Flutter的YouTube视频教程-小部件
上节课回顾
- Scaffold 小组件
相当于 iOS的ViewController 或者Android的 Activity
看作一个界面- AppBar 相当于 Tabbar
- StatelessWidget 是不能存放变量的 因为是继承 Widget 因为 Widget 使用了 @immutable 这个修饰用来 当前这个类是不可变的 或者子类是不可变的.所有的成员变量必须是 final的
- StatefulWidget 分成2个类
一个是继承 StatefulWidget的类(最主要作用是 必须实现State类,还有一个作用是 可以接受父Widget 传过来的数据),
一个是State类(状态)
stless
代码智能提示快速创建一个继承于 StatelessWidget
的类
依次做Widget树结构
App
HomePage
-> 包含 Scaffold
Scaffold
-> 包含 AppBar -> Title
-> 包含 body : HomeContent
HomeContent -> Ttile
import 'package:flutter/material.dart'; // runApp在这个material库里面 // 使用箭头函数 main() => runApp(MyApp()); // <stlss> 使用代码只能提示 快速创建一个继承与 StatelessWidget 的类 class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home:YHiOSHomePage() , ); } } class YHiOSHomePage extends StatelessWidget { const YHiOSHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 主页 使用一个小组件 Scaffold return Scaffold( appBar: AppBar( title: Text("商品列表"), ), body: YHiOSHomeContent(), ); } } class YHiOSHomeContent extends StatelessWidget { const YHiOSHomeContent({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Text("hello world"); } }
Column
Widget 创建列表商品数据都是写死的
该代码的注意细节:
- 抽取列表的每一个item为Widget
- 定义几个变量来记录 item的数据
- 使用Image.network加载网络的图片
import 'package:flutter/material.dart'; // runApp在这个material库里面 // 使用箭头函数 main() => runApp(MyApp()); // <stlss> 使用代码只能提示 快速创建一个继承与 StatelessWidget 的类 class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home:YHiOSHomePage() , ); } } class YHiOSHomePage extends StatelessWidget { const YHiOSHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 主页 使用一个小组件 Scaffold return Scaffold( appBar: AppBar( title: Text("商品列表"), ), body: YHiOSHomeContent(), ); } } class YHiOSHomeContent extends StatelessWidget { const YHiOSHomeContent({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ YHiOSHomeProductItem("清风衬晚霞1","清风衬晚霞 desc1","https://wx3.sinaimg.cn/mw2000/515a7464ly1h01enjqtdmj20j60j6q3k.jpg"), YHiOSHomeProductItem("清风衬晚霞2","清风衬晚霞 desc2","https://wx2.sinaimg.cn/orj360/515a7464ly1h01enjqdo4j20j60j6t9b.jpg"), YHiOSHomeProductItem("清风衬晚霞3","清风衬晚霞 desc3","https://wx2.sinaimg.cn/orj360/515a7464ly1h01enjqx21j20j60j60tc.jpg"), YHiOSHomeProductItem("清风衬晚霞4","清风衬晚霞 desc3","https://wx2.sinaimg.cn/orj360/515a7464ly1h01enjrqa9j20j60j6q3n.jpg"), ], ); } } // ⭐️ 抽取商品的item /** * 包含 : * 标题 * 详细 * 图片 * */ // 每个item的数据 都是不一样的 所以需要定义几个变量来标记数据 class YHiOSHomeProductItem extends StatelessWidget { final String title ; final String desc ; final String imageURL ; // 构造函数 YHiOSHomeProductItem(this.title,this.desc,this.imageURL); @override Widget build(BuildContext context) { return Column( children: [ Text(title), Text(desc), Image.network(imageURL) ], ); } }
我们发现在底部多出了一块警告的区域
relayoutBoundary=up1 OVERFLOWING
布局边界
如何解决
我们需要把Column
Widget 改成ListView
Widget
YHiOSHomeContent
Column
Widget 改成 ListView
Widget 效果图 就能解决上面出现的警告区域了TextStyle
抽取字体大小、颜色 和 通过 SizedBox
设置上下的间距class YHiOSHomeProductItem extends StatelessWidget { final String title ; final String desc ; final String imageURL ; final style1 = TextStyle(fontSize: 25,color: Colors.orange); final style2 = TextStyle(fontSize: 20,color: Colors.red); // 构造函数 YHiOSHomeProductItem(this.title,this.desc,this.imageURL); @override Widget build(BuildContext context) { return Column( children: [ Text(title,style: style1), SizedBox(height: 8), Text(desc,style: style2), SizedBox(height: 8), Image.network(imageURL) ], ); } }
alt + enter
快捷键 进行输出一个Container
对象 用来设置内外边距的 边框的大小和颜色BoxDecoration 设置边框的大小 颜色
padding : EdgeInsets 设置边框的大小
// 每个item的数据 都是不一样的 所以需要定义几个变量来标记数据 class YHiOSHomeProductItem extends StatelessWidget { final String title ; final String desc ; final String imageURL ; final style1 = TextStyle(fontSize: 25,color: Colors.orange); final style2 = TextStyle(fontSize: 20,color: Colors.red); // 构造函数 YHiOSHomeProductItem(this.title,this.desc,this.imageURL); @override Widget build(BuildContext context) { return Container( // decoration 装饰 // BoxDecoration 是一个子类 padding: EdgeInsets.all(30), decoration: BoxDecoration( border: Border.all( width: 5, // 设置边框的宽度 color:Colors.purple // 设置边框的颜色 ) ), child: Column( children: [ Text(title,style: style1), SizedBox(height: 8), Text(desc,style: style2), SizedBox(height: 8), Image.network(imageURL) ], ), ); } }
crossAxisAlignment
Column的垂直方向是主轴 |
Row的水平方向是主轴 –
// ⭐️ 抽取商品的item /** * 包含 : * 标题 * 详细 * 图片 * */ // 每个item的数据 都是不一样的 所以需要定义几个变量来标记数据 class YHiOSHomeProductItem extends StatelessWidget { final String title ; final String desc ; final String imageURL ; final style1 = TextStyle(fontSize: 25,color: Colors.orange); final style2 = TextStyle(fontSize: 20,color: Colors.red); // 构造函数 YHiOSHomeProductItem(this.title,this.desc,this.imageURL); @override Widget build(BuildContext context) { return Container( // decoration 装饰 // BoxDecoration 是一个子类 padding: EdgeInsets.all(30), decoration: BoxDecoration( border: Border.all( width: 5, // 设置边框的宽度 color:Colors.purple // 设置边框的颜色 ) ), child: Column( // 主轴 // mainAxisAlignment: MainAxisAlignment.center, // 交叉轴 crossAxisAlignment: CrossAxisAlignment.end, children: [ Text(title,style: style1), SizedBox(height: 8), Text(desc,style: style2), SizedBox(height: 8), Image.network(imageURL) ], ), ); } }
可以点击指定的Widget 通过 option + enter 包裹一个row
Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text(title,style: style1), ], ),
- 1
- 2
- 3
- 4
- 5
- 6
// ⭐️ 抽取商品的item /** * 包含 : * 标题 * 详细 * 图片 * */ // 每个item的数据 都是不一样的 所以需要定义几个变量来标记数据 class YHiOSHomeProductItem extends StatelessWidget { final String title ; final String desc ; final String imageURL ; final style1 = TextStyle(fontSize: 25,color: Colors.orange); final style2 = TextStyle(fontSize: 20,color: Colors.red); // 构造函数 YHiOSHomeProductItem(this.title,this.desc,this.imageURL); @override Widget build(BuildContext context) { return Container( // decoration 装饰 // BoxDecoration 是一个子类 padding: EdgeInsets.all(30), decoration: BoxDecoration( border: Border.all( width: 5, // 设置边框的宽度 color:Colors.purple // 设置边框的颜色 ) ), child: Column( // 主轴 // mainAxisAlignment: MainAxisAlignment.center, // 交叉轴 crossAxisAlignment: CrossAxisAlignment.end, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text(title,style: style1), ], ), SizedBox(height: 8), Text(desc,style: style2), SizedBox(height: 8), Image.network(imageURL) ], ), ); } }
stful
代码智能提示快速创建一个继承于 StatefulWidget
的类StatefulWidget 中 的 Widget 和 State 注意点
- Widget
StatefulWidget 是一个抽象类
有一个方法是 必须实现的
createState
Widget是不加 _ 因为Wighet是暴露给别人使用的- State
State是加_ : 状态这个是给Widget使用的
Flutter设计StatefulWidget的原理
/** * 为什么Flutter在设计的时候 StatefulWidget 的build方法放在State * 1.build出来的Widget是需要依赖State中的变量(状态/数据) * 2.在Flutter的运行过程中: * Widget是不断地销毁和创建的 * 当我们自己的状态发生改变时,并不希望重新创建一个新的State * */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Row
嵌套两个 RaisedButton
按钮 用来记录加减号的// 为什么有些Widget是child 有些是children .最主要是看继承关系. // child 只是包含一个Widget // 有些是children 可以包含多个Widget
- 1
- 2
- 3
当代码嵌套比较多 可以使用抽取方法
比如 两个RaisedButton
// 抽取方法 用于获取按钮 Widget _getButtons() { return Row( children: [ RaisedButton( child: Text("+"), color: Colors.pink, onPressed: () => print("点击了+") ), RaisedButton( child: Text("-"), color: Colors.orange, onPressed: () => print("点击了-") ), ], ); }
import 'package:flutter/material.dart'; // runApp在这个material库里面 // 使用箭头函数 main() => runApp(MyApp()); // <stlss> 使用代码只能提示 快速创建一个继承与 StatelessWidget 的类 class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home:YHiOSHomePage() , ); } } class YHiOSHomePage extends StatelessWidget { const YHiOSHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 主页 使用一个小组件 Scaffold return Scaffold( appBar: AppBar( title: Text("商品列表"), ), body: YHiOSHomeContent(), ); } } // StatefulWidget 是一个抽象类 // 有一个方法是 必须实现的 // createState // Widget是不加 _ 因为Wighet是暴露给别人使用的 class YHiOSHomeContent extends StatefulWidget { @override State<StatefulWidget> createState() { return _YHiOSHomeContentState(); } } // State的代码规范是 以_开头 // State是加_ : 状态这个是给Widget使用的 /** * 为什么Flutter在设计的时候 StatefulWidget 的build方法放在State * 1.build出来的Widget是需要依赖State中的变量(状态/数据) * 2.在Flutter的运行过程中: * Widget是不断地销毁和创建的 * 当我们自己的状态发生改变时,并不希望重新创建一个新的State * */ class _YHiOSHomeContentState extends State<YHiOSHomeContent> { int _counter = 0; @override Widget build(BuildContext context) { return Center( // 为什么有些Widget是child 有些是children .最主要是看继承关系. // child 只是包含一个Widget // 有些是children 可以包含多个Widget child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _getButtons(), Text("当前计数:$_counter",style:TextStyle(fontSize: 30)) ], ), ); } // 抽取方法 用于获取按钮 Widget _getButtons() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ RaisedButton( child: Text("+",style: TextStyle(fontSize: 20,color: Colors.white)), color: Colors.pink, onPressed: () { // 刷新页面 状态更新 setState(() { _counter++; }); } ), RaisedButton( child: Text("-",style: TextStyle(fontSize: 20,color: Colors.white)), color: Colors.orange, onPressed: () { setState(() { _counter--; }); } ), ], ); } }
// StatelessWidget的生命周期
class YHiOSHomeContent extends StatelessWidget {
final String message;
YHiOSHomeContent(this.message){
print("构造函数被调用");
}
@override
Widget build(BuildContext context) {
print("调用build方法");
return Text(message);
}
}
class YHiOSHomeContent extends StatefulWidget { YHiOSHomeContent(){ print("1.调用了 YHiOSHomeContent 的 constructor方法"); } @override _YHiOSHomeContentState createState() { print("2.调用了 YHiOSHomeContent 的 createState方法"); return _YHiOSHomeContentState(); } } class _YHiOSHomeContentState extends State<YHiOSHomeContent> { _YHiOSHomeContentState() { print("3.调用了 _YHiOSHomeContentState 的 constructor方法"); } void initState(){ // 调用: 这里是必须调用 super // super.initState(); print("4.调用了 _YHiOSHomeContentState 的 initState方法"); } @override Widget build(BuildContext context) { print("5.调用了 _YHiOSHomeContentState 的 build方法"); return Container(); } @override void dispose() { // TODO: implement dispose print("6.调用了 _YHiOSHomeContentState 的 dispose方法"); super.dispose(); } }
因为系统内部已经做了处理 只有调用setState方法之后 .才会重新build
import 'package:flutter/material.dart'; // runApp在这个material库里面 // 使用箭头函数 main() => runApp(MyApp()); // <stlss> 使用代码只能提示 快速创建一个继承与 StatelessWidget 的类 class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home:YHiOSHomePage() , ); } } class YHiOSHomePage extends StatelessWidget { const YHiOSHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 主页 使用一个小组件 Scaffold return Scaffold( appBar: AppBar( title: Text("商品列表"), ), // body: YHiOSHomeContent("你好呀 宇夜iOS"), body: YHiOSHomeContent(), ); } } // StatelessWidget的生命周期 // class YHiOSHomeContent extends StatelessWidget { // final String message; // // YHiOSHomeContent(this.message){ // print("构造函数被调用"); // } // @override // Widget build(BuildContext context) { // print("调用build方法"); // return Text(message); // } // } // StatefulWidget的生命周期 // class YHiOSHomeContent extends StatefulWidget { YHiOSHomeContent(){ print("1.调用了 YHiOSHomeContent 的 constructor方法"); } @override _YHiOSHomeContentState createState() { print("2.调用了 YHiOSHomeContent 的 createState方法"); return _YHiOSHomeContentState(); } } class _YHiOSHomeContentState extends State<YHiOSHomeContent> { int _counter = 0; _YHiOSHomeContentState() { print("3.调用了 _YHiOSHomeContentState 的 constructor方法"); } void initState(){ // 调用: 这里是必须调用 super // super.initState(); print("4.调用了 _YHiOSHomeContentState 的 initState方法"); } @override Widget build(BuildContext context) { print("5.调用了 _YHiOSHomeContentState 的 build方法"); return Column( children: [ RaisedButton( child: Icon(Icons.add), onPressed: (){ setState(() { _counter ++; }); }, ), Text("数字:$_counter") ], ); } @override void dispose() { // TODO: implement dispose print("6.调用了 _YHiOSHomeContentState 的 dispose方法"); super.dispose(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。