1、初始化
void main() => runApp(new FirstWidget());
class FirstWidget extends StatelessWidget {
Widget first = new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: Scaffold(
appBar: AppBar(title: Center(child: Text('我是标题'))),
drawer: Text('这是抽屉栏'),
body: Text('你好,这是一个简单的页面'),
),
);
@override
Widget build(BuildContext context) => first;
}
=> expr
胖箭头语法是 { return expr; }
形式的缩写。
所以初始化函数实际上是
void main(){
return runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context){
return new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: Scaffold(
appBar: AppBar(title: Center(child: Text('我是标题'))),
drawer: Text('这是抽屉栏'),
body: Text('你好,这是一个简单的页面'),
),
);
}
}
在编写应用程序时,通常会创建新的widget,这些widget是无状态的
StatelessWidget
或者是有状态的StatefulWidget
, 具体的选择取决于您的widget是否需要管理一些状态。widget的主要工作是实现一个build
函数,用以构建自身。一个widget通常由一些较低级别widget组成。Flutter框架将依次构建这些widget,直到构建到最底层的子widget时,这些最低层的widget通常为RenderObject
,它会计算并描述widget的几何形状。StatefulWidget 拥有 StatelessWidget 的所有功能,也就是说 StatelessWidget 是他的子集,每个StateFulWidget 维护一个 State 对象,当我们对 相关数据更新后 并且 调用了** setState(() {})** 方法,这样就吧 该 Widget 标记为 dirty ,因此会触发控件的更新、替换、删除 等。
上面的runApp
函数接受给定的Widget
并使其成为widget树的根,框架强制根widget覆盖整个屏幕。所以官方不推荐把Widget层的控件来作为根控件,而是以MaterialApp或者WidgetApp作为父节点,上面的MyApp使用build函数构建了一个MaterialApp,将一个Scaffold脚手架包裹在里面,Scaffold显示的才是整个页面
2、MaterialApp/WidgetApp
class MaterialApp extends StatefulWidget
MaterialApp的主要作用是定义一些整体的风格,设置一些整体属性。构建一个material design风格的App。
- MaterialApp 引入了 Material Design,还是相当漂亮的,开发者几乎不需要做额外的布局、样式 编码就能达到产品级视觉效果, 当然可以根据需求进行微调。
- MaterialApp 提供了大量的美观、功能丰富的控件,放弃MaterialApp等于放弃了一整片森林。
MaterialApp 主要属性如下:
- title : 在任务管理窗口中所显示的应用名字
- theme : 应用各种 UI 所使用的主题颜色
- color : 应用的主要颜色值(primary color),也就是安卓任务管理窗口中所显示的应用颜色
- home : 应用默认所显示的界面 Widget
- routes : 应用的顶级导航表格,这个是多页面应用用来控制页面跳转的,类似于网页的网址
- initialRoute :第一个显示的路由名字,默认值为 Window.defaultRouteName
- onGenerateRoute : 生成路由的回调函数,当导航的命名路由的时候,会使用这个来生成界面
- onLocaleChanged : 当系统修改语言的时候,会触发这个回调
- navigatorObservers : 应用 Navigator 的监听器
- debugShowMaterialGrid : 是否显示 纸墨设计 基础布局网格,用来调试 UI 的工具
- showPerformanceOverlay : 显示性能标签,https://flutter.io/debugging/#performanceoverlay
- checkerboardRasterCacheImages 、showSemanticsDebugger、debugShowCheckedModeBanner 各种调试开关
3、Scaffold
class Scaffold extends StatefulWidget
Scaffold中文名脚手架,如果说MaterialApp是定义整个App主体、主题之类的角色,Scaffold就是针对当前页面的一个架构了,其中的提供了一些组件属性
appBar:顶部标题栏
body:用来展示 APP 的主体部分。主体部分大部分是通过组合 Container ,Column,Row,Stack来实现的
floatingActionButton:悬浮按钮
bottomNavigationBar:底部类Tab导航栏
drawer:左边侧边栏控件
endDrawer:右边侧滑栏
backgroundColor: 内容的背景颜色,默认使用的是 ThemeData.scaffoldBackgroundColor 的值
4、布局/Flex
在main函数中开启网格调试布局
debugPaintSizeEnabled=true;
flutter采用Flex布局。
child
可承载单个子控件,children
可承载多个子控
- Container:如果要添加填充,边距,边框或背景色,请使用Container来设置,只有Container有这些属性
- Row:child在水平(左右)方向上进行布局
- Colomn:child在竖直(上下)方向上进行布局
- Expanded:填充剩余空间,必须放置于Row, Column或Flex内,
- Stack+Positoned:Stack与Row和Clomn类似,只不过适用于子Wight没那么规则化的布局,可以允许其子widget简单的堆叠在一起
5、添加本地资源
在根目录下新建文件夹,命名为images,将lake.png图片放入
在pubspec.yam中添加
flutter:
assets:
- images/lake.png
- images/background.png
如果要,包含images文件夹下的所有文件,可以简化为
flutter:
assets:
- images/
在代码中访问,比如:
new Image.asset(
'images/lake.jpg', //图片的路径
width: 600.0, //图片控件的宽度
height: 240.0, //图片控件的高度
fit: BoxFit.cover, //告诉引用图片的控件,图像应尽可能小,但覆盖整个控件。
),
有一些系统的Icons可以直接访问
Icons.call // 电话图标
6、定位/Alignment
在Widget内设置alignment属性,是为了给child/children定位,
alignment: Alignment.center,
7、Stack
Stack可用于一些位置没有那么比例化的Row以及Cloumn
child: Stack(
children: <Widget>[
Positioned(
right: 10.0,
top: 24.0,
width: 20,
height: 20,
child: new Container(
color: Colors.blue,
),
)],
这种情况还有一个方法是用Row来布局,Row内先加一个Expand来拓张,然后接一个所需要的控件,再接一个控件用来与边界的距离
8、Tabbar使用
_tabController = new TabController(vsync: this, length: 3);
Widget actionCountBar() => new Container(
height: 50,
child: new TabBar(
controller: _tabController,
tabs: <Widget>[
new Tab(
text: '转发0',
),
new Tab(
text: '评论5',
),
new Tab(
text: '点赞1',
),
],
),
);
Widget actionTabView()=> new Container(
height: 500,
child: new TabBarView( // 这是不同的页面
controller: _tabController,
children: <Widget>[
new Center(child: new Text('转发')),
new Center(child: new Text('评论')),
new Center(child: new Text('点赞')),
],
),
);
需要注意的是,controller要预先生成
9、NestedScrollView嵌套ScrollView
NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverToBoxAdapter(
child: listHeaderView(),
),
];
},
body: Column(
children: <Widget>[
actionCountBar(),
actionTabView(items),
],
)),
headerSliverBuilder
:头部,相当于UITableView的HeadView
SliverToBoxAdapter
:新建普通的
body
:放置ScrollView