小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
一切皆是Widget
在Flutter里面,一切皆是Widget。Widget是最基础的组件,所有的类,最后返回的都是Widget。在iOS里面的UILabel、UIButton、UITextField、UIImageView、UIView等一切视图组件,在Flutter里面都是Widget,甚至于iOS里面的UIViewController、UINavigationController、UITabbarController,安卓里面的Activity,在Flutter里都是Widget。总结一句,我们能看到的一切都是Widget。
官方Widget
介绍官方Widget,其实就是介绍官方UI组件。后面所有的自定义组件都是基于这些基础组件组合变化得来。写Flutter对这些组件肯定要烂熟于心,就跟记UIView、UILabel、UIButton一样,当然这些基础组件也不难,写一遍看一下视图呈现,基本就能搞明白了。
这里推荐一个Github项目flutter-study,介绍了很多Widget,一开始写的时候我对组件不熟悉的时候,会回过头去参考一下,很有用。
Text
Text 可以用来在应用内创建带样式的文本。
Text('You have pushed the button this many times:')
Row, Column
Row和Column是最常用最基本的Widget,几乎所有的最后成型的视图都是由这个搭成的。Row代表横向排列,Column代表纵向排列,这两个组件写过前端的朋友应该是比较熟悉的。因为它是基于 web 的 flexbox 布局模型设计的。
示例代码:
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
Row(children: [Text('横向排列0 '), Text('横向排列1')],)
],
),
Container
Container 可以用来创建一个可见的矩形元素。当然它也可以使用 BoxDecoration 来进行装饰,如背景,边框,或阴影等。Container 还可以设置外边距、内边距和尺寸的约束条件等。一般会包裹一些其它组件,而自己又需要有背景色或者阴影的时候用。
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Container(color: Colors.blue, width: 100, height: 100,),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Stack
Stack 是覆盖布局,这个Stack不要被iOS的UIStackView混淆,哈哈,这里的Stack是Z轴上的视图叠加,使用场景比如以下这两种
这两种应该是比较常见的,下面给出第一种案例的示例代码,里面会涉及一些其他组件,这边也顺带提一下
- Padding,内边距
- GestureDetector, 带点击手势,可以添加响应事件
- ClipRRect, 圆角
Widget _buildHead(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 28),
child: GestureDetector(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
alignment: Alignment.bottomRight,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(45),
child: Image.asset(
'res/assets/head.jpg',
width: 90,
height: 90,
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.only(bottom: 10),
child: ImageFactory.camera,
)
],
)
],
),
),
);
}
ListView
ListView是列表视图,就是iOS的UITableView,官方建议用builder方法创建,会有内存回收机制,类似于iOS的复用机制。
// ListView最基础创建
Widget listDemo() {
return ListView.builder(
itemCount: 10, // item的数量
itemBuilder: (context, index) {
// 呈现的item组件
return Text('data');
});
}
// ListView带分割线的创建
Widget listSepDemo() {
return ListView.separated(
itemBuilder: (context, index) {
// 呈现的item组件
return Text('data');
},
separatorBuilder: (context, index) {
// 呈现的item组件
return Container(
height: 1,
color: Colors.grey,
);
},
itemCount: 10);
}
不带分割线
带分割线
GridView
GridView是网格视图,就是iOS的UICollectionView,一样,官方建议用builder方法创建,会有内存回收机制,类似于iOS的复用机制。gridDelegate就是配置一些网格的属性,比如横向间距、纵向间距等。
Widget gridDemo() {
return GridView.builder(
itemCount: 10,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, crossAxisSpacing: 10, mainAxisSpacing: 10),
itemBuilder: (context, index) {
return Container(
color: Colors.green,
width: 100,
height: 100,
);
});
}
GridView-网格视图
总结
以上这些基础组件已经能满足大部分场景了,初期入门也不用把所有组件都熟悉,可以在写的过程中,如果发现有特殊的视图,再去查找。
那么,第二篇就先到这吧,学习之路道阻且长,咱们后会有期,😝 😝 😝