flutter作为移动开发创建应用的新方式,和iOS开发相比起来还是有一些区别的,这篇文章挑几个容易混淆的点来说明。
重点:Flutter一定要记住:万物皆widget!
views和widget
在iOS开发中,我们每天接触最多的就是各种控件,UIViwe,UIButton,UIImageview等等。其中UIView是最基本的界面组成单位,继承自UIResponder,承担了界面显示和用户交互的作用,像按钮,图片,输入框等UIView的大量子类也为我们提供了快速构建界面的便利。他们具有添加子视图(addsubview)的方法来容纳其他的view,最终构成我们想要的界面。
在Flutter当中,在UI的创建方式上面你可以把widget想象成和UIViwe一样的作用。你可以想象一个APP页面是有不同的widget来组成的,导航栏是widget,图片是widget,cell是widget,按钮也是widget。
但是widget又和UIViwe不同。
1 生命周期不同,UIview创建后你可以通过setNeedsDisplay来实现自身的重绘,而当widget改变时候,Flutter 会通过setstate构建一颗新的 widgets 树。
2widget概念更广。widget是一种UI界面的创建方式,也可以是布局的方式(Row,Column等),也可以负责用户交互(GestureDetector),也可以负责APP的样式,也可以管理动画,真的是万物皆widget。
自定义和组合
在iOS开发当中,如果系统的组件不能满足设计师的要求,我们通常会继承该控件,在当中做一些工作来实现自己的需求。
在Flutter当中,面对设计师精美个性的UI,我们更多的是利用各种基础的widge通过各种方式组合到一起来合成一个更大的widget。(因为widget本身是没有任何具体的UI形态的)。举个例子,Container是一个常用的widget, 由多个widget组成,这些widget负责布局、绘制、定位和调整大小。具体来说,Container由 LimitedBox、 ConstrainedBox、 Align、 Padding、DecoratedBox、 和Transform组成。 您可以用各种方式组合这些以及其他简单的widget,而不是继承。
ViewController与Flutter
前面我们已经提过,iOS开发中,界面是由大量的UIView构建的,通常情况下,我们习惯于每一个独立的界面交付给一个ViewController来管理,每一个ViewController持有UIView并且负责管理。
在Flutter当中是没有控制器的概念的,ViewController起到的作用同样有widget来承担,万物皆widget,你可以想象一个Flutter开发的APP的每一个界面都是大大小小的widget。
更新视图的对比
iOS中,我们想要更新视图的话我们是直接操作视图本身的,比如我们想要改变UIView的颜色,我们直接.color= ,我们改变视图的大小,直接操纵他们的frame。但是在Flutter当中,widgets 是不可变的,而且不能被直接更新。你需要去操纵 widget 的 state。利用setstate方法通知Flutter去改变这个widget的状态。
widget分为StatelessWidget(无状态)和StatefulWidget(有状态)两大类,无状态StatelessWidget的widget一旦创建就不可改变,适用于一些固定死的文案,icon,图标。有状态StatefulWidget的widget则适用于一些显示什么取决于后台数据的视图(widget)。通常情况下,我们取到http请求回来的数据后,通过调用改widget的setstate方法,把要改变的状态赋值,Flutter就会重绘widget树。
处理用户交互
在iOS中,我们处理用户交互大概分为两大类,1是直接创建继承自UIControl的控件,例如按钮UIButton, 输入框等等,2是想UIImageview这类控件我们会通过添加手势的方式来处理用户交互。
Flutter中,也有封装好的Button类,例如RaisedButton,FlatButton,CupertinoButton,他们有onPress的方法,你可以实现这个来完成。如果是Container,Text,Image这类,通常我们会在外面再包一个GestureDetector手势widget,把我们想要有交互功能的控件作为GestureDetector的child,再实现onTap方法来实现,例子如下
GestureDetector(
onTap: () {
setState(() { _lights = true; });
},
child: Container(
color: Colors.yellow,
child: Text('TURN LIGHTS ON'),
),
)
addSubview()和removeFromSuperview()
在iOS中我们很多时候会在父 view 中调用 addSubview() 或在子 view 中调用 removeFromSuperview() 来动态地添加或移除子 views。
Flutter中,因为widget不可变属性,没有相应的添加或者移除视图的方法。作为替代,你可以向 parent 传入一个返回 widget 的函数,并用一个布尔值来控制子 widget 的创建。这种设计,也导致了在Flutter开发过程中有着大量的开关存在。例子如下:
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
@override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
// Default value for toggle
bool toggle = true;
void _toggle() {
setState(() {
toggle = !toggle;
});
}
_getToggleChild() {
if (toggle) {
return Text('Toggle One');
} else {
return CupertinoButton(
onPressed: () {},
child: Text('Toggle Two'),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample App"),
),
body: Center(
child: _getToggleChild(),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
tooltip: 'Update Text',
child: Icon(Icons.update),
),
);
}
}
...继续填坑中
参考资料:https://flutterchina.club/flutter-for-ios/#flutter-for-ios-%E5%BC%80%E5%8F%91%E8%80%85
网友评论