发表日期:2018-12 文章编辑:小灯 浏览次数:3302
Widget 是每个 Flutter 应用的基础。每个 Widget 是一部分用户界面上不可变的定义。和其他框架把 View、controller、 Layout 和其他资源分开定义不一样,Flutter 具有一致的、唯一的对象模型: Widget。
一个 Widget 可以定义:
Widget 通常通过组合的方式来构建复杂的 UI。例如,常用的 Container Widget 就是由几个分别负责 布局、绘制、布局和计算大小的 Widget 组成。具体来说,Container 由
等widget 组成。如果要自定义 Container 来实现自定义效果,相比使用继承而言,可以使用组合一些简单的 Widget 实现自定义效果。
[图片上传失败...(image-84ef2a-1543882561066)]
主要文章: widget概述-布局模型
Flutter有一套丰富、强大的基础widget,其中以下是很常用的:
Text:该 widget 可让创建一个带格式的文本。
Row、 Column: 这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。
Stack: 取代线性布局 (译者语:和Android中的LinearLayout相似),Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。
Container: Container 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
flutter提供了友好的Widget 的查找地址,可以方便的找到自己组要的组件:
什么是重点?
- 有些widgets是有状态的, 有些是无状态的
stateless widget 没有内部状态. Icon、 IconButton, 和Text 都是无状态widget, 他们都是StatelessWidget的子类。
stateful widget 是动态的. 用户可以和其交互 (例如输入一个表单、 或者移动一个slider滑块),或者可以随时间改变 (也许是数据改变导致的UI更新). Checkbox, Radio, Slider, InkWell, Form, and TextField 都是 stateful widgets, 他们都是 StatefulWidget的子类。
创建一个有状态的widget
- 要创建一个自定义有状态widget,需创建两个类:StatefulWidget和State
- 有多种方法可以管理状态.
一下是常见状态管理的几种方法
如何决定使用哪种管理方法?以下原则可以帮助您决定:
平台方法调用
平台方法调用主要分四步:
平台事件调用
平台事件调用和方法调用类似,步骤如下:
除了上面提到的MethodChannel,你还可以使用BasicMessageChannel,它支持使用自定义消息编解码器进行基本的异步消息传递。 此外,您可以使用专门的BinaryCodec,StringCodec和 JSONMessageCodec类,或创建自己的编解码器。
在Flutter中系统为我们提供了可以加载图片的控件Image,Image 控件提供了如下几种用于加载不同方式的图片。
在flutter中Image支持JPEG, PNG, GIF, Animated GIF, WebP, Animated WebP, BMP, 和 WBMP这几种图片格式。
今天我们主要介绍下两种常用的方式,从asset目录和从network获取图片
从asset目录加载图片
1. 新建存放图片的目录 想要使Image加载asset加载apk内部的图片,首先需要在项目中建立放置图片的目录(名称随意,不要中文就好) 我们在lib目录的同级目录建立images文件夹,并在里面放置了一个cover.jpg的图片2. 更细配置文件pubspec.yaml 在flutter节点下新增 文件声明 ,如下所示 flutter: assets:- images/cover.jpg3. 加载目录中的图片文件 new Image.asset("images/helloflutter.png")
从network获取图片
基本上和上面asset的参数相同,只不过从网络获取的方式可以传入请求头。
但是,从我网络获取图片展示的调用方式就比从asset读取显示方便的多,只需要一行代码就可以搞定
把Scaffold body的参数写为:
new Image.network("http://pic1.win4000.com/wallpaper/2017-10-25/59f083092ed4f.jpg")
注:本篇文档官方使用的是用dart io中的HttpClient发起的请求,但HttpClient本身功能较弱,很多常用功能都不支持。我们建议您使用dio 来发起网络请求,它是一个强大易用的dart http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载……详情请查看github dio
处理异步
注意,HTTP API 在返回值中使用了Dart Futures。 我们建议使用async/await语法来调用API。
网络调用通常遵循如下步骤:
get() async { var httpClient = new HttpClient(); var uri = new Uri.http( 'example.com', '/path1/path2', {'param1': '42', 'param2': 'foo'}); var request = await httpClient.getUrl(uri); var response = await request.close(); var responseBody = await response.transform(UTF8.decoder).join(); }
Flutter给我们提供了第三发库的支持,同样的下面三个操作
var url = "http://example.com/whatsit/create"; http.post(url, body: {"name": "doodle", "color": "blue"}) .then((response) { print("Response status: ${response.statusCode}"); print("Response body: ${response.body}"); });
官网还退出了一个网络第三方库 github dio
Dio dio = new Dio();_loadDataByDio() async { try { Response response = await dio.get("https://news-at.zhihu.com/api/4/news/latest"); if (response.statusCode == HttpStatus.ok) { _result = response.data.toString(); } else { _result = 'error code : ${response.statusCode}'; } } catch (exception) { print('exc:$exception'); _result = '网络异常'; }setState(() {}); }
静态路由
在Flutter中有着两种路由跳转的方式,一种是静态路由,在创建时就已经明确知道了要跳转的页面和值。另一种是动态路由,跳转传入的目标地址和要传入的值都可以是动态的。
OK,还是先来介绍下静态路由
从我们开始学习Flutter到现在,相信大家看到最多的肯定是下面的代码
void main() { runApp(new MaterialApp( home: new MyApp(), routes: <String, WidgetBuilder>{ '/page2': (BuildContext context) => new Page2("requestString"), }, )); }
routes: const {}
routes需要传入类型的Map,第一个参数是目标路由的名称,第二个参数就是你要跳转的页面。
这种定义路由并使用的方式非常的简单,但是大家肯定会发现一个问题,就是如果我需要传递给第二个页面的数据不是已知的话我就无法使用这种方式,因为我们无法动态改变上面定义的值。
所以,我们就需要了解下Flutter中的动态路由了。
动态路由
在Navigator中还有一个方法是push()方法,需要传入一个Route对象,在Flutter中我们可以使用PageRouteBuilder来构建这个Route对象。
Navigator.of(context).push(new PageRouteBuilder( pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { return new Page2("some attrs you like ");}))
这样的话,我们就可以把用户操作与交互的数据传递给下个页面。
页面出栈
在Flutter中我们可以使用Navigator.of(context).pop()进行出栈操作,但是值得注意的时如果页面上有Dialog、BottomSheet、popMenu类似的Widget使用pop()方法会优先进行这些Widget的关闭操作。
处理出栈页面返回值
在前面我们介绍到Navigator.of(context).pop()可以使得页面出栈,当然这个pop方法也是可以传值的,只用Navigator.of(context).pop(attrs)就可以传入自己想要返回的值
Future future = Navigator.of(context).pushNamed("/pageB"); future.then((value) { showDialog( context: context, child: new AlertDialog( title: new Text(value), )); }
小结
官网提供了很多好用的插件,插件地址
等等。。。其他科自行搜索使用。
如果你想开发一个新的插件可以参考开发Packages和插件
日期:2018-10 浏览次数:7171
日期:2018-12 浏览次数:4237
日期:2018-07 浏览次数:4796
日期:2018-12 浏览次数:4085
日期:2018-09 浏览次数:5418
日期:2018-12 浏览次数:9833
日期:2018-11 浏览次数:4727
日期:2018-07 浏览次数:4505
日期:2018-05 浏览次数:4777
日期:2018-12 浏览次数:4240
日期:2018-10 浏览次数:5060
日期:2018-12 浏览次数:6127
日期:2018-11 浏览次数:4381
日期:2018-08 浏览次数:4512
日期:2018-11 浏览次数:12532
日期:2018-09 浏览次数:5493
日期:2018-12 浏览次数:4754
日期:2018-10 浏览次数:4101
日期:2018-11 浏览次数:4448
日期:2018-12 浏览次数:5973
日期:2018-06 浏览次数:3919
日期:2018-08 浏览次数:5354
日期:2018-10 浏览次数:4384
日期:2018-12 浏览次数:4410
日期:2018-07 浏览次数:4273
日期:2018-12 浏览次数:4422
日期:2018-06 浏览次数:4299
日期:2018-11 浏览次数:4283
日期:2018-12 浏览次数:4166
日期:2018-12 浏览次数:5198
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.