从 RN 到 Flutter-部件
在 Flutter 中,你应该使用部件去描述针对于现有状态和配置的界面。
部件是由许多很小或者单一目的的部件组成。比如Container部件就包括几个相关布局、绘制、定位和定型组件,像是LimitedBox、ConstrainedBox、Align、Padding、DecoratedBox以及Transform部件。除了使用Container来实现效果,你也可以用几个组件来实现它。
Center部件是另一个控制布局的例子。想要剧中部件,就用Center包住它。这些部件没有自己的展示,他们的目标就是控制内部部件的布局。想要理解部件是如何渲染,可以去查看他们的相邻部件。
了解更多信息,可以查看Flutter 技术概览。
想要了解更多部件信息,可以查看Flutter 基础部件,Flutter 部件目录 或者 Flutter 部件索引。
界面
Flutter 中的 View 组件
在 React Native 中,View是支持Flexbox布局、样式处理、触摸处理和无障碍化的组件。
在 Flutter 中,你可以使用诸如Container、Column Row和Center的核心布局部件。更多信息可以参考布局部件目录。
Flutter 中的 FlatList 和 SectionList 组件
一个List是垂直排布的可滚动列表。
在 React Native 中,FlatList和SectionList可以用来渲染简单的或者复杂内容的列表。
<FlatList data={[]} renderItem={({ item }) => <Text>{item.key}</Text>} />
ListView是 Flutter 中最常被使用的滚动部件。默认的构造器接受一列准确定义的数据。ListView适合少量个数部件渲染。对于无限滚动,需要使用ListView.builder,它会按需渲染,并之渲染能展示出来的数据。
var data = [];
ListView.builder(
itemCount: data.length,
itemBuilder: (context, int index) {
return Text(data[index]);
},
);
| Adroid ListVIew | iOS ListView |
|---|---|
![]() | ![]() |
阅读你的第一个 Flutter 应用,第一部分更多了解如何实现无限滚动。
如何使用画布
在 React Native 中是没有相关组件的,需要引入类似于react-native-canvas的第三方组件。
const App = () => {
return (
<View>
<Canvas
ref={(canvas) => {
const ctx = canvas.getContext("2d");
ctx.fillStyle = "skyblue";
ctx.beginPath();
ctx.arc(75, 75, 50, 0, 2 * Math.PI);
ctx.fillRect(150, 100, 300, 300);
ctx.stroke();
}}
/>
</View>
);
};
在 Flutter 中,你可以使用CustomPaint和CustomPainter类去绘制画布。
下面的例子展示的是如何使用CustomPaint部件绘制。它实现了虚类 CustomPainter,并传递了 CustomPaint 的属性。CustomPaint 的子类必须实现 paint() 和 shouldRepaint() 方法。
class MyCanvasPainter extends CustomPainter {
paint(Canvas anvas, Size size) {
{
Paint paint = Paint();
paint.color = Colors.amber;
canvas.drawCircle(Offset(100.0, 200.0), 40.0, paint);
}
{
Paint paint = Paint();
paint.color = Colors.lightBlue;
Rect rect = Rect.fromPoints(Offset(150.0, 300.0), Offset(300.0, 400.0));
canvas.drawRect(rect, paintRect);
}
}
shouldRepaint() => false;
}
Widget getCanvas() {
return Scaffold(
body: CustomPaint(
paint: MyCanvasPainter(),
),
);
}
| Android CustomPaint | iOS CustomPaint |
|---|---|
![]() | ![]() |
布局
如何使用布局部件
在 React Native,许多布局可以通过 props 传入。比如,你可以使用View的style属性去指定 flexbox 布局。想要让组件成列排列,可以指定样式为flexDirection: "column"。
<View
style={{
flex: 1,
flexDirection: "column",
justifyContent: "space-between",
alignItems: "center"
}}
/>
在 Flutter 中,布局主要是由既定的布局部件和他们的参数实现。
举个例子,Column和Row组件接受一个数组作为参数来以列或者以行排列。一个Container部件既能处理样式也能处理布局,一个Center部件可以将组件居中。
Center(
child: Column(
children: <Widget> [
Container(
color: Colors.red,
width: 100.0,
height: 100.0,
),
Container(
color: Colors.blue,
width: 100.0,
height: 100.0
),
Container(
color: Colors.green,
width: 100.0,
height: 100.0,
),
],
),
)
Flutter 提供一堆布局部件,比方说,Padding、Align和Stack。
了解全部的布局部件,可以查看布局部件。
| Adroid Layout | iOS Layout |
|---|---|
![]() | ![]() |
如何堆叠部件
在 React Native,可以使用绝对定位absolute来堆叠组件。
Flutter 使用Stack部件让部件按照图层分布。部件会部分覆盖于下面的部件。
Stack(
alignment: cont Alignment(0.6, 0.6),
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(
'https://avatars3.githubusercontent.com/u/14101776?v=4'
)
),
Container(
decoration: BoxDecoration(
color: Colors.black45,
),
child: Text("Flutter"),
),
],
)
上面的例子使用Stack来布局一个Container并展示一个拥有黑色半透明背景的Text部件覆盖于CircleAvatar部件。这个部件通过对齐参数来规定文字位置。
| Android Stack | iOS Stack |
|---|---|
![]() | ![]() |
更多信息可以查看Stack对象文档。
样式
如何处理组件样式
在 React Native 中,内联样式和stylesheets.create是用来处理组件样式的。
const style = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
<View style={styles.container}>
<Text style={{ fontSize: 32, color: "cyan", fontWeight: "600" }}>
This is a simple text
</Text>
</View>;
在 Flutter 中,Text部件可以使用TextStyle类,这个类的对象也可以给多个部件复用。
var textStyle = TextStyle(
fontSize: 32.0,
color: Colors.cyan,
fontWeight: FontWeight.w600,
);
Center(
child: Column(
children: <Widget>[
Text(
'sample text',
style: textStyle,
),
Padding(
padding: EdgeInsets.all(20.0),
child: Icon(
Icons.lightbulb_outline,
size: 48.0,
color: Colors.redAccent,
),
),
],
),
)
| Android Style | iOS Style |
|---|---|
![]() | ![]() |
如何使用图标和颜色
React Native 没有支持图标的库(这点我不是很同意)。
在 Flutter 中,引入 Material 库包含一堆Material 图标和颜色。
Icon(Icons.lightbulb_outline, color: COlors.redAccent)
使用Icons类时,记住要把uses-material-design: true设置在pubspec.yaml中。这保证MaterialIcons字体会被包括在应用中。
name: my_awesome_application
flutter:
uses-material-design: true
Flutter 的Cupertino包,完全遵守 iOS 设计语言。要使用CupertinoIcons字体,在项目中增加cupertino_icons依赖。
name: my_awesome_application
dependencies:
cupertino_icons: ^0.1.0
要完全的自定义组件的色彩和样式,使用ThemeData来定义主题。设置MaterialApp的ThemeData对象。Colors类提供遵守 Material 设计语言的调色盘。
Widget build() {
return MaterialApp(
title: "Sample App",
theme: ThemeData(
primarySwatch: Colors.blue,
textSelectionColor: Colors.red,
),
home: SampleAppPage()
);
}
如何增加主题样式
在 Ract Native,主题是组件定义好的。
在 Flutter 中,使用ThemeData类为整个MaterialApp部件提供主题。
Widget build() {
return MaterialApp(
title: "Sample App",
theme: ThemeData(
primarySwatch: Colors.blue,
textSelectionColor: Colors.red,
),
home: SampleAppPage()
);
}
一个Theme甚至可以不依赖于MaterialApp部件。Theme部件需要一个ThemeData传入它的data参数中,以适配它的所有子部件。
class SampleTheme extends StatelessWidget {
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
primaryColor: Colors.cyan,
brightness: brightness,
),
child: Scaffold(
backgroundColor: Theme.of(context).primaryColor,
)
)
}
}








