Plugin & Package
Package: Dart中的第三方框架,里面只有Dart的代码Plugin: 包含安卓和iOS原生的代码
Flutter & RN
Flutter:有一套自己的渲染引擎,不依赖原生UI,效率高,高度统一。RN:基于原生的UI进行的包装,一旦原生的更新,马上也需要更新。
Widget
material.dar类似于iOS中的UIKit,在Flutter中有一个组件的概念(widget),下面的代码中CenterText都继承于widget ,flutter中没有图层的概念,只有一层。
import 'package:flutter/material.dart';void main() {runApp(Center(child: Text('hello world',textDirection: TextDirection.ltr, // 阅读方向,不写则不显示), // Text的构造) // Center的构造);}

自定义Widget
有状态的stateful:可以更改
无状态的stateless:不能更改
继承StatelessWidget必须要实现一个方法:Widget build(BuildContext context)
void main() {runApp(MyWidget());}//上面的可以写成箭头函数void main() => runApp(MyWidget());class MyWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return Center(child: Text('hello world',textDirection: TextDirection.ltr,),);}}
�在Flutter中创建的对象没有说再赋值给某一个指针变量,一般都是直接构造使用。
class MyWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return Center(child: Text('hello world',textDirection: TextDirection.ltr,style: TextStyle(color: Colors.yellow,fontWeight: FontWeight.bold,),),);}}
MaterialApp
Flutter里面提供了一个封装的比较好的MaterialApp
import 'package:flutter/material.dart';void main() => runApp(App());class App extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: MyWidget(),);}}class MyWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return Center(child: Text('hello world',textDirection: TextDirection.ltr,style: TextStyle(color: Colors.yellow,fontWeight: FontWeight.bold,),),);}}

运行之后发现出现了一个debug的标识符,打开MaterialApp的构造说明,发现里面有一个默认值this.debugShowCheckedModeBanner = true我们把它修改为false这个标识就没有了。
Scaffold
一般的开发中MaterialApp会搭配Scaffold来使用
class App extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: Text('flutterDemo'),),body: MyWidget(),));}}
此时MyWidget中的文字居中是相对于Body居中的。
�
模型对象
构造函数的参数使用{}修饰表示的是可选参数,可以参考下文档中的widget的构造
class Car {Car({this.name, this.imageUrl});final String? name;final String? imageUrl;}// 测试数据final List<Car> datas = [const Car(name: '保时捷918 Spyder',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '兰博基尼Aventador',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '法拉利Enzo',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: 'Zenvo ST1',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '迈凯伦F1',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '萨林S7',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '科尼赛克CCR',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '布加迪Chiron',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '轩尼诗Venom GT',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',),const Car(name: '西贝尔Tuatara',imageUrl:'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',)];
ListView
把scaffold抽取出来,同时body使用ListView()
class App extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: Home(),);}}class Home extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('flutterDemo'),),);}}
listView的构造函数�ListView.builder(itemBuilder: itemBuilder)点击进去发现是一个回调required IndexedWidgetBuilder itemBuilder,继续点击IndexedWidgetBuilder发现这个typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index)这个跟iOS中指定每一个indexPath的cell一样。所以我们来实现一个这样的方法
class Home extends StatelessWidget {Widget _itemForRow(BuildContext context, int index) {return Text(datas[index].name!);}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('flutterDemo'),),body: ListView.builder(itemBuilder: _itemForRow,itemCount: datas.length,),);}}

这里介绍一个Container组件
Widget _itemForRow(BuildContext context, int index) {return Container(color: Colors.white,margin: EdgeInsets.all(10),child: Image.network(datas[index].imageUrl!),);}

组件的排列只有三种:横着、竖着和叠着。
但是Container内部只能装有一个child,我们可以使用组件的排列的样式来布局
Widget _itemForRow(BuildContext context, int index) {return Container(color: Colors.white,margin: EdgeInsets.all(10),child: Column(children: [Image.network(datas[index].imageUrl!),Text(datas[index].name!)],));}

加载的时候是异步加载的,因为首先显示的是文字等到图片资源回来之后更新排版。
TIPS
如果AS强退会锁死。当我们再次打开的时候会有点问题,所以一旦锁死的时候,我们可以来到这里/flutter/bin/cache/lockfile把这个删掉就行Flutter中文网:中文网Dart package: pub
