Flutter 和 RN
Flutter能够在Android 和iOS 上同时运行的原因是iOS和Android上面都安装了Flutter的渲染引擎,而RN则是在原生UI的基础上进行包装,那么一旦原生的UI更新,RN就也需要更新,进行兼容处理,并且RN让Android的显示Android的控件,iOS显示iOS的控件,那么就不是一套UI。Flutter将渲染引擎安装在了手机上,那么久导致Flutter的包会很大,因为里面包含了渲染引擎,但是他优点是效率高,并且不依赖原生的UI,iOS和android 的页面高度统一。
Flutter 页面
基础页面
在ios开发中开发页面需要导入UIKit,那么在Flutter中也有类似的库也就是material。
import 'package:flutter/material.dart;
在ios开发中,需要在window中开发视图,而在Flutter中需要执行一个函数runApp传入一个widget。这里的child相当于subview。 这里看到Center有下划线,因为这里都是静态的界面,不会改变,所以会报警告,建议添加const变成一个常量。Flutter渲染是增量渲染。在ios中,会监控页面的属性,哪个属性变了,那么就会重新渲染一下。而在Flutter中,则是会重新渲染一整个界面,哪个界面发生改变,那么就重新渲染这个界面,而不会观察属性。
自定义widget
在Widget中主要分为两大类,一个是有状态(StatefulWidget)的,一个是无状态(StatelessWidget)的。顾名思义,无状态的不能改变,而有状态的则是内部的小部件可以变化他的状态。其实本质上Flutter中都是无状态的,有状态是因为通过定义了很多功能,方便开发者进行开发,变成有状态的。这里必须实现build方法来进行渲染。
import 'package:flutter/material.dart';
void main() {
runApp(
const Center(
child:MyWidget(),
)
);
}
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Center(
child:Text(
'hello Flutter',
textDirection: TextDirection.ltr,
),
);
}
}
Flutter中的部件创建出来都是为了当时用的,当属性改变就会创建新的界面,旧的界面就被丢弃了,没有复用的概念。这里为Text添加style。可以看到这里都是用的构造函数来创建,如果赋值了就会用这个值来生成,如果没有赋值就会用默认值或者不处理。
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Center(
child:Text(
'hello Flutter',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
color:Colors.red,
),
),
);
}
}
MaterialApp & Scaffold
一般我们会用到MaterialApp来初始化页面,用Scaffold来搭建页面。这里AppBar就相当于Navigation title,
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title:const Text(
"Flutter demo"
),
),
body: const MyWidget(),
),
);
}
}
运行后就是这个样子。
ListView
首先创建一个新文件,创建一个模型:
class Car {
Car({this.name,this.imageUrl});
final String? name;
final String? imageUrl;
}
修改一下结构
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"Flutter demo"
),
),
body: MyWidget(),
);
}
}
接下来开始写ListView。这里需要两个参数,一个itemBuilder,一个itemCount。这里的itemBuilder是一个回调函数,返回Widget,有两个参数,一个是context,一个是index,就像是cellForRow方法 这里就创建一个方法来当作参数。
class Home extends StatelessWidget {
Widget _itemForRow(BuildContext context, int index) {
return Text(datas[index].name ?? "");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"Flutter demo"
),
),
body: ListView.builder(itemBuilder:_itemForRow ,itemCount: datas.length,),
);
}
}
运行后得到: 修改一下:
class Home extends StatelessWidget {
Widget _itemForRow(BuildContext context, int index) {
return Container(
color: Colors.white,
margin:EdgeInsets.all(10),
child: Column(
children: [
Image.network(datas[index].imageUrl ?? ""),
SizedBox(height: 10,),
Text(datas[index].name ?? ""),
],
)
);
}
|