Flutter跨平台移动端开发丨Padding、Constrai
2019-05-24 本文已影响0人
MobMsg
目录
- Padding(间距)
- ConstrainedBox(约束盒)
- SizeBox(固定盒)
- UnconstrainedBox(无约束盒)
- DecoratedBox(装饰盒)
- Container(组合容器)
- Scaffold Widget and TabBar Widget(脚手架及切换组件)
Padding(间距)
使用 padding 标签可以给子 widget 添加间距
const Padding({
Key key,
@required this.padding,
Widget child,
}) : assert(padding != null),
super(key: key, child: child);
- all:指定四个方向使用同一间距
- fromLTRB:四个方向间距分别制定
- only:指定单一具体方向间距
- symmetric:设置对称方向间距(vertical = top+bottom,horizontal = left+right)
/**
* @des Padding Widget
* @author liyongli 20190424
* */
class PaddingWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _PaddingState();
}
/**
* @des Padding Widget State
* @author liyongli 20190424
* */
class _PaddingState extends State<PaddingWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Padding Widget"),
),
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: RaisedButton(
child: Text("四个方向间距统一"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.fromLTRB(0.0,20.0,40.0,20.0),
child: RaisedButton(
child: Text("分别指定四个方向"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.only(left:40.0),
child: RaisedButton(
child: Text("单一方向添加边距"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20.0),
child: RaisedButton(
child: Text("对称方向添加边距"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
),
],
)
),
);
}
// 按钮点击监听
void _BtnClick(){
print("不设置点击事件按钮会是灰色的!");
}
}
ConstrainedBox(约束盒)
constrainedBox 可以给子 widget 添加更多约束条件。与 sizedBox 同通过 renderConstrainedBox 绘制
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity
});
- minWidth:子 widget 最小宽度
- maxWidth:子 widget 最大宽度
- minHeight:子 widget 最小高度
- maxHeight:子 widget 最大高度
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
return new RenderConstrainedBox(
additionalConstraints: ...,
);
}
/**
* @des ConstrainedBox Widget
* @author liyongli 20190424
* */
class ConstrainedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ConstrainedBoxState();
}
/**
* @des ConstrainedBox Widget State
* @author liyongli 20190424
* */
class _ConstrainedBoxState extends State<ConstrainedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("ConstrainedBox Widget"),
),
body: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 50.0,
minWidth: double.infinity
),
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
)
),
)
);
}
// 按钮点击监听
void _BtnClick(){
print("不设置点击事件按钮会是灰色的!");
}
}
SizeBox(固定盒)
sizedBox 可以给子 widget 指定宽高。与 constrainedBox 同通过 renderConstrainedBox 绘制
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
return new RenderConstrainedBox(
additionalConstraints: ...,
);
}
/**
* @des SizedBox Widget
* @author liyongli 20190424
* */
class SizedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _SizedBoxState();
}
/**
* @des SizedBox Widget State
* @author liyongli 20190424
* */
class _SizedBoxState extends State<SizedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("SizedBox Widget"),
),
body: SizedBox(
width: double.infinity,
height: 80.0,
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
)
),
)
);
}
// 按钮点击监听
void _BtnClick(){
print("不设置点击事件按钮会是灰色的!");
}
}
UnconstrainedBox(无约束盒)
unconstrainedBox 允许子 widget 按照自有属性绘制,可用作去除父 widget 限制
/**
* @des UnconstrainedBox Widget
* @author liyongli 20190424
* */
class UnconstrainedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _UnconstrainedBoxState();
}
/**
* @des UnconstrainedBox Widget State
* @author liyongli 20190424
* */
class _UnconstrainedBoxState extends State<UnconstrainedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("UnconstrainedBox Widget"),
),
body: SizedBox(
width: double.infinity,
height: 80.0,
child: UnconstrainedBox(
child: RaisedButton(
child: Text("A"),
color: Colors.blue ,
textColor: Colors.white,
onPressed: _BtnClick,
),
)
),
)
);
}
// 按钮点击监听
void _BtnClick(){
print("不设置点击事件按钮会是灰色的!");
}
}
虽然从效果来看,父 widget 的限制没有起作用,但是实际上它只是没有影响子 widget 的大小,但还是占有了响应的空间
DecoratedBox(装饰盒)
decoratedBox 可以给子 widget 绘制前、后增添一个装饰
const DecoratedBox({
Key key,
@required this.decoration,
this.position = DecorationPosition.background,
Widget child
}) : assert(decoration != null),
assert(position != null),
super(key: key, child: child);
- decoration:即将绘制的装饰
- position:绘制时间。background = 在子 widget 之后绘制,foreground = 在子 widget 之前绘制
- child:子 widget
/**
* @des DecoratedBox Widget
* @author liyongli 20190425
* */
class DecoratedBoxWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _DecoratedBoxState();
}
/**
* @des DecoratedBox Widget State
* @author liyongli 20190425
* */
class _DecoratedBoxState extends State<DecoratedBoxWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("DecoratedBox Widget"),
),
body: DecoratedBox(
// 装饰
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
boxShadow: [
BoxShadow(
color: Colors.blue,
offset: Offset(5.0, 5.0),
blurRadius: 20.0
)
]
),
// 主体
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0,horizontal: 40.0),
child: Text("flutter", style: TextStyle(color: Colors.white ),),
),
),
)
);
}
}
Container(组合容器)
container 是各种我们已知的 widget 的组合,使用它可以实现装饰、变换、限制等各种效果
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
),
decoration = decoration ?? (color != null ? BoxDecoration(color: color) : null),
constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints,
super(key: key);
- width、height:当一级标签与 constraints 中同时包含 width、height 时,一级标签优先
/**
* @des Container Widget
* @author liyongli 20190425
* */
class ContainerWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ContainerState();
}
/**
* @des Container Widget State
* @author liyongli 20190425
* */
class _ContainerState extends State<ContainerWidget>{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Container Widget"),
),
body: Container(
margin: EdgeInsets.only(left:70.0), //容器外间距
constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), //卡片大小
// 装饰
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
gradient: LinearGradient(colors: [Colors.blue,Colors.purpleAccent]),
boxShadow: [
BoxShadow(
color: Colors.blue,
offset: Offset(5.0, 5.0),
blurRadius: 20.0
)
]
),
transform: Matrix4.rotationZ(0.2), //卡片倾斜变换
alignment: Alignment.center, //卡片内文字居中
child: Text("flutter", style: TextStyle(color: Colors.white ),),
)
)
);
}
}
Scaffold Widget and TabBar Widget(脚手架及切换组件)
scaffold 是 Materrial 库中提供的一个脚手架,可以帮助开发者更快的完成功能页的开发
const Scaffold({
Key key,
this.appBar,
this.body,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.floatingActionButtonAnimator,
this.persistentFooterButtons,
this.drawer,
this.endDrawer,
this.bottomNavigationBar,
this.bottomSheet,
this.backgroundColor,
this.resizeToAvoidBottomPadding,
this.resizeToAvoidBottomInset,
this.primary = true,
this.drawerDragStartBehavior = DragStartBehavior.down,
}) : assert(primary != null),
assert(drawerDragStartBehavior != null),
super(key: key);
- key:当前元素的唯一标识符(类似于 Android 中的 id)
- appBar:顶部导航栏
- body:主体部分
- floatingActionButton:悬浮按钮
- drawer:抽屉部件
- bottomNavigationBar:底部导航栏
模拟商品详情页骨架
/**
* @des Scaffold Widget
* @author liyongli 20190426
* */
class ScaffoldWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ScaffoldState();
}
/**
* @des Scaffold Widget State
* @author liyongli 20190426
* */
class _ScaffoldState extends State<ScaffoldWidget>{
@override
Widget build(BuildContext context) {
return Scaffold(
// 导航栏
appBar: AppBar( title: Text("Detail"),
centerTitle: true,
elevation: 3.0,
leading: Builder(builder: (context){
return IconButton(
iconSize: 20.0,
icon: Icon(Icons.arrow_back_ios, color: Colors.white,),
onPressed: _finishBtn,
);
}),
actions: <Widget>[
IconButton(
iconSize: 20.0,
icon: Icon(Icons.favorite_border, color: Colors.white,),
onPressed: _collectionBtn,
),
IconButton(
iconSize: 20.0,
icon: Icon(Icons.share, color: Colors.white,),
onPressed: _moreBtn,
),
],
),
// 悬浮按钮
floatingActionButton: FloatingActionButton(
child: Icon(Icons.shopping_cart),
onPressed: _shoppingBtn,),
);
}
// finish
void _finishBtn(){
print("finish");
}
// shared
void _collectionBtn(){
print("shared");
}
// float
void _moreBtn(){
print("shared");
}
// shopping
void _shoppingBtn(){
print("shared");
}
}
模拟新闻类APP骨架
/**
* @des Scaffold and TabBar Widget
* @author liyongli 20190426
* */
class ScaffoldAndTabBarWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => new _ScaffoldAndTabBarState();
}
/**
* @des Scaffold and TabBar Widget State
* @author liyongli 20190426
* */
class _ScaffoldAndTabBarState extends State<ScaffoldAndTabBarWidget>
with SingleTickerProviderStateMixin {
TabController _tabController;
List tabs = ["热点","综合","科技","教育","财经"];
int _selectedIndex = 0;
@override
void initState() {
super.initState();
_tabController = new TabController(length: tabs.length, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// 导航栏
appBar: AppBar(
title: Text("News Home", style: TextStyle(fontSize: 16.0),),
centerTitle: true,
elevation: 3.0,
leading: Builder(builder: (context){
return IconButton(
iconSize: 20.0,
icon: Icon(Icons.person, color: Colors.white,),
onPressed: _finishBtn,
);
}),
actions: <Widget>[
IconButton(
iconSize: 20.0,
icon: Icon(Icons.message, color: Colors.white,),
onPressed: _moreBtn,
),
],
bottom: TabBar( //生成Tab菜单
controller: _tabController,
tabs: tabs.map((e) => Tab(text: e)).toList()
),
),
bottomNavigationBar: BottomNavigationBar( // 底部导航
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.message), title: Text('Message')),
BottomNavigationBarItem(icon: Icon(Icons.person), title: Text('personal')),
],
currentIndex: _selectedIndex,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
body: TabBarView(
controller: _tabController,
children: tabs.map((e) { //创建3个Tab页
return Container(
alignment: Alignment.center,
child: Text(e, textScaleFactor: 5),
);
}).toList(),
),
);
}
// finish
void _finishBtn(){
print("finish");
}
// shared
void _collectionBtn(){
print("shared");
}
// float
void _moreBtn(){
print("shared");
}
// shopping
void _shoppingBtn(){
print("shared");
}
void _onItemTapped(int index) {
}
}
本篇到此完结,更多 Flutter 跨平台移动端开发 原创内容持续更新中~
期待您 关注 / 点赞 / 收藏 向着 大前端工程师 晋级!