Widget(小部件)定义:
在 iOS 中,构建 UI 的过程中将大量使用 view 对象。这些对象都是 UIView 的实例。它们可以用作容器来承载其他的 UIView,最> 终构成你的界面布局。
在 Flutter 中,你可以粗略地认为 Widget 相当于 UIView 。Widget 和 iOS 中的控件并不完全等价,但当你试图去理解 Flutter 是> 如何工作的时候,你可以认为它们是“声明和构建 UI 的方法”。
然而,Widget 和 UIView 还是有些区别的。首先,widgets 拥有不同的生存时间:它们一直存在且保持不变,直到当它们需要被>改变。当 widgets 和它们的状态被改变时,Flutter 会构建一颗新的 widgets 树。作为对比,iOS 中的 views 在改变时并不会被重>新创建。但是与其说 views 是可变的实例,不如说它们被绘制了一次,并且直到使用 setNeedsDisplay() 之后才会被重新绘制。
为了更系统的了解Flutter的结构我们从 0 开始创建一个App
首先打开我们之前创建的项目打开main.dart ,为了熟悉一下代码结构,我们删除 main.dart 中所有代码。我们来自己写一个。
在iOS中我们编写页面首先需要import UIKit, Flutter 也一样有个类似的操作我们需要导入 material.dart
import 'package:flutter/material.dart';
入口函数:
iOS 中有个入口函数main,Flutter也一样有个main函数作为入口函数:
/// 入口函数 相当于 main 函数
void main() {
// runApp 相当于 UIApplicationMain(argc, argv, nil, appDelegateClassName)
// runApp 里面的参数 相当于 设置 Appdelegate 但又不完全相像 这个参数相当于设置根
// widget 更像直接设置 rootViewController
runApp(
/// Center 就是系统提供的一个 Widget (这里写Center 就相当于UIApplicationMain设置 Appdelegate 的操作 )
Center(
// 这里的child: 有的说可以理解为addSubview ,但因为他只能设置一个,所以我理解为 手动设置 Center Widget 的layer,
// 注意 textDirection: TextDirection.ltr,为必填
child: Text("Home ",textDirection: TextDirection.ltr,),
));
}
widget 的两种分类
/// statelessWidget (相当于不可变组件)、statefulwidget (相当于可变组件)
/// ps:有状态只是有一个状态类保存了他的状态 ( 因为 UI 本身就是没有状态的)
所以我们可以这样理解,一个widget就是一个类,就是一个继承自 statelessWidget或statefulwidget的类,类似于我们iOS中继承UIView自定义一个View。
在iOS中我们自定义一个 UIView 我们需要 把子view 一个个 addSubview 。Flutter 这没有这用语法,它是通过利用:Build 方法来添加的
class ssssss extends StatelessWidget {
// 其实这就是 图层数 不需要我们手动 addSubview
/// build 方法会将 build 方法所包含的视图 渲染
@override
Widget build(BuildContext context) {
return Container(
child:Text('My Text', TextDirection.rtl),
);
}
}
这里把 main 函数中 runapp 里面 Center.child 后面的 Text 小部件 修改为 ssssss() 这个我们刚刚创建的小部件。
到此我们自定义了一个小部件。
下面我们看看一些预置的小部件。
Text
Text
该 widget 可让创建一个带格式的文本。
Text(
'titlewwwView',
textDirection: TextDirection.ltr,
)
Row Column
Row
、 Column
childrens 相当于 addSubviews
return Column(
children: [
Text(datas[index].name),
Image.network(datas[index].imgUrl)
],
);
这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。
Stack
Stack 是叠加布局
Stack
* [`Stack`](https://docs.flutter.io/flutter/widgets/Stack-class.html): 取代线性布局 (译者语:和Android中的LinearLayout相似),[`Stack`](https://docs.flutter.io/flutter/widgets/Stack-class.html)允许子 widget 堆叠, 你可以使用 [`Positioned`](https://docs.flutter.io/flutter/widgets/Positioned-class.html) 来定位他们相对于`Stack`的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。
iOS 也有 UIStackView 这很容易对应起来
Container
Container
这个我觉得 更贴近于 UIView , 这个是一个纯粹的 视图容器
他就跟 UIView 十分相似 需要 frame 也就是 坐标 宽高
不设置高度就是 autoLayout
另有区别 就是 他的子小控件 用 child 来添加
-
Container
:Container
可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration
, 如 background、一个边框、或者一个阴影。Container
也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外,Container
可以使用矩阵在三维空间中对其进行变换。
class BaseWidgetDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
Container(
/// 内间距
padding: EdgeInsets.only(left: 10, top: 20, bottom: 20, right: 10),
/// 外间距
margin: EdgeInsets.only(top: 10, left: 20, bottom: 10, right: 20),
child: Text("AAAAA"),
),
Container(
child: Text("ddddd"),
),
],
);
}
}
MaterialApp
MaterialApp 是一个 根widget ,对于 iOS 我们需要设根导航控制器MaterialApp是Flutter提供给我们的一个根小部件。它有以下属性
title : 在任务管理窗口中所显示的应用名字
theme : 应用各种 UI 所使用的主题颜色
color : 应用的主要颜色值(primary color),也就是安卓任务管理窗口中所显示的应用颜色
home : 应用默认所显示的界面 Widget
routes : 应用的顶级导航表格,这个是多页面应用用来控制页面跳转的,类似于网页的网址
initialRoute :第一个显示的路由名字,默认值为 Window.defaultRouteName
onGenerateRoute : 生成路由的回调函数,当导航的命名路由的时候,会使用这个来生成界面
onLocaleChanged : 当系统修改语言的时候,会触发这个回调
navigatorObservers : 应用 Navigator 的监听器
debugShowMaterialGrid : 是否显示 Material design 基础布局网格,用来调试 UI 的工具
showPerformanceOverlay : 显示性能标签
checkerboardRasterCacheImages 、showSemanticsDebugger、debugShowCheckedModeBanner 各种调试开关
Scaffold
iOS 开发中我们肯定会写 UINavigationController, Scaffold 就相当于 UINavigationController,
他有一个title属性,这个属性就相当于navigation的titleView。所以它的参数是一个 Widget类型。
另外他有一个 Body 属性,这个属性就是相当于 给 navigationcontroller设置rootViewController,只不过这里是试着Widget
Scaffold(
appBar: AppBar(
title: Text(
'titlewwwView',
textDirection: TextDirection.ltr,
),
),
body: ssssss(),
),
ListView
这个很容易理解 就相当于 UITableView
final List datas = [
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
];
class ListViewDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: datas.length, // 相当于 numberOfRowsInSection
itemBuilder: (context, index) { // 相当于 CellForRowAtIndexPath
return Column(
children: [
Text(datas[index].name),
Image.network(datas[index].imgUrl)
],
);
},
);
}
}
class Car {
const Car(
this.name,
this.imgUrl,
);
final String name;
final String imgUrl;
}
以上代码效果图:
RichText 富文本
这里的富文本比 iOS 差不多,其实都是拼接,但不如iOS那个灵活舒服我感觉。Flutter 的 RichText 其实就是套娃的感觉
class RichTextDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RichText(
text: TextSpan(
text: '这里是富文本这里是富文本呼呼哈哈',
style: TextStyle(fontSize: 18, color: Colors.red),
children: [
/// 这里一直铺下去即可
TextSpan(text: 'hhhh', style: TextStyle(color: Colors.blue)),
TextSpan(text: 'hhhh', style: TextStyle(color: Colors.red)),
TextSpan(text: 'hhhh', style: TextStyle(color: Colors.yellow)),
],
),
);
}
}
下一篇:Flutter 布局、state、Dart语法简单入门