学习Flutter的一点记录,主要是怕自己忘~
基本的快捷键
Android studio 中
-
首先在Terminal中输入命令将项目跑起来
flutter run
-
显示网格 按下 P 键
-
切换ios显示 按下O 键
-
热更新按键是 command+\
VScode中
-
使用
flutter run
运行项目 -
p显示网格,o是切换安卓和ios系统
-
按下 r 键热更新。
-
删除一行:command+shift+k
-
复制一行:shift+option+⬆️或⬇️
-
按住 option 再单击:选中多个光标
-
创建新项目需要在Terminal 下使用命令
flutter create 项目名称
,
Flutter控件-ImageView
- 看下基本的代码
void main() => runApp(WudanImageViewPage());
class WudanImageViewPage extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Class Name',
home: Scaffold(
appBar: AppBar(title: Text('UIImageView')),
body: Center(
child: Image.network(//加载的是网络的图片
"url",
fit: BoxFit.cover,//fit 填充方式很多种
),
),
),
);
}
}
-
加载方式
- Image.asset:加载资源图片,就是加载项目资源目录中的图片,加入图片后会增大打包的包体体积,用的是相对路径。
- Image.network:网络资源图片
- Image.file:加载本地图片,就是加载本地文件中的图片,这个是一个绝对路径,跟包体无关。
- Image.memory:加载Uint8List资源图片
-
fit属性
fit属性可以控制图片的拉伸和挤压,这些都是根据图片的父级容器来的。看下常用的几个
BoxFit.fill:
全图显示,图片会被拉伸,并充满父容器。BoxFit.contain
:全图显示,显示原比例,可能会有空隙。
BoxFit.cover
:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。BoxFit.fitWidth
:宽度充满(横向充满),显示可能拉伸,可能裁切。BoxFit.fitHeight
:高度充满(竖向充满),显示可能拉伸,可能裁切。BoxFit.scaleDown
:效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大。 -
图片的混合模式
图片混合模式(colorBlendMode)和color属性配合使用,能让图片改变颜色,里边的模式非常的多,产生的效果也是非常丰富的。
child: Image.network( 'url, color: Colors.greenAccent, colorBlendMode: BlendMode.darken, ),
Flutter控件-ListView
-
基本操作-竖向列表展示
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('flutter hot')), body: new ListView( children: <Widget>[//数组,里面是单个的条目 new ListTile( leading: new Icon(Icons.access_alarm), title: new Text("这是一个闹钟") ), new ListTile( leading: new Icon(Icons.perm_camera_mic), title: new Text("perm_camera_mic") ), new ListTile( leading: new Icon(Icons.call_end_rounded), title: new Text("call_end_rounded") ), ], ) )); } }
-
基本操作-横向列表展示
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('ListView')), body: Center( child: Container(//指定一个外层的容器 height: 200.0, child: new ListView( scrollDirection: Axis.horizontal,//指定横向 children:<Widget> [//子条目是一个个容器 new Container( width: 180.0, color: Colors.greenAccent, ), new Container( width: 180.0, color: Colors.blueAccent, ), new Container( width: 180.0, color: Colors.yellowAccent, ), new Container( width: 180.0, color: Colors.redAccent, ), ], ), ), ) )); } }
Axis是一个枚举类型
enum Axis { /// Left and right. /// /// See also: /// /// * [TextDirection], which disambiguates between left-to-right horizontal /// content and right-to-left horizontal content. horizontal, /// Up and down. vertical, }
-
基本操作-动态列表展示
-
List类型的使用
List是Dart的集合类型之一,其实你可以把它简单理解为数组(反正我是这么认为的),其他语言也都有这个类型。它的声明有几种方式:
var myList = List()
: 非固定长度的声明。var myList = List(2)
: 固定长度的声明。var myList= List<String>()
:固定类型的声明方式。var myList = [1,2,3]
: 对List直接赋值。
我们这里使用的是一个List传递,然后直接用List中的
generate
方法进行生产List里的元素。最后的结果是生产了一个带值的List变量。代码如下:void main () => runApp(MyApp( items: new List<String>.generate(1000, (i)=> "Item $i")//generate是对list赋值 ));
generate方法
第一个指定长度,第二个参数是方法
List.generate(int length, String Function(int) generator, { bool growable = true})
-
参数的接收
- 代码如下:
final List<String> items;//声明一个成员变量 MyApp({ Key key, this.items}):super(key:key);
这是一个构造函数,除了Key,我们增加了一个必传参数,这里的
@required
意思就必传。:super
如果父类没有无名无参数的默认构造函数,则子类必须手动调用一个父类构造函数。这样我们就可以接收一个传递过来的参数了,当然我们要事先进行声明。
-
报错
The parameter 'key' can't have a value of 'null' because of its type 'Key', but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier. MyApp{ Key key, this.title}) : super(key: key);
这是因为 flutter版本升级对相关调用类构造方法添加了空判断导致的。
我们可以用官方推荐的修改方式修改即Key ?key来表示可空,又因为title是final修饰量,final修饰的常量必须在声明进初始化或者在构造函数中初始化,它的值可以动态计算。 所以可以添加required修饰要求必须作为参数填入。
修改后
MyApp({ Key? key, this.items}):super(key: key);
-
完整代码如下
import 'package:flutter/material.dart'; void main() => runApp(MyApp( items: new List<String>.generate(1000, (i) => 'item is ${ i}'), )); class MyApp extends StatelessWidget { final List<String>? items; //构造 传递参数Key 是默认参数 MyApp({ Key? key, this.items}):super(key: key); Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('ListView')), body: new ListView.builder(//利用builder 来创建列表 itemCount: items!.length, itemBuilder: (context,index){ return new ListTile( title: new Text('${ items![index]}'), ); }, ) )); } }
-
-
抽取定义的组件
可以将定义的ListView进行封装,使得代码结构简洁,举个例子:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('ListView')), body: Center( child: Container(//指定一个外层的容器 height: 200.0, child:new MyListView() ,//将上边的例子封装一个widget ), ) )); } } class MyListView extends StatelessWidget{ Widget build(BuildContext context) { return new ListView( scrollDirection: Axis.horizontal,//指定横向 children:<Widget> [//子条目是一个个容器 new Container( width: 180.0, color: Colors.greenAccent, ), new Container( width: 180.0, color: Colors.blueAccent, ), new Container( width: 180.0, color: Colors.yellowAccent, ), new Container( width: 180.0, color: Colors.redAccent, ), ], ); } }
Flutter控件-GridView
-
基本使用
代码如下
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('ListView')), body: GridView.count( crossAxisCount: 3, //横向是三列 padding: const EdgeInsets.all(10.0),//内边距设置 crossAxisSpacing: 5, //网格间的横向边距 children: const [ Text("这是第一个元素"), Text("这是第二个元素"), Text("这是第三个元素"), Text("这是第四个元素"), Text("这是第五个元素"), ], //填充数据 ))); } }
-
直接使用GridView 构造的方式
-
SliverGridDelegateWithFixedCrossAxisCount
可以直接指定每行(列)显示多少个Item,其中两个属性:
主轴即纵轴
- mainAxisSpacing: 2.0,//主轴的间隔大小
- mainAxisExtent: 100,//主轴的长度
-
SliverGridDelegateWithMaxCrossAxisExtent
会根据GridView的宽度和你设置的每个的宽度来自动计算没行显示多少个Item
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'text widget', home: Scaffold( appBar: AppBar(title: Text('GridView')), body: GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 2.0,//主轴的间隔大小 mainAxisExtent: 100,//主轴的长度 crossAxisSpacing: 2.0,//横向的间隔 childAspectRatio: 0.7),//横竖比 children: [//子条目 Image.network( 'http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg', fit: BoxFit.cover), Image.network( 'http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg', fit: BoxFit.cover), Image.network( 'http://img5.mtime.cn/mt/2018/11/13/093605.61422332_180X260X4.jpg', fit: BoxFit.cover), Image.network( 'http://img5.mtime.cn/mt/2018/11/07/092515.55805319_180X260X4.jpg', fit: BoxFit.cover), ], ))); } }
-