这里用到Flutter的Stack,最近整体学完一遍后再仔细看看文档写博客。
Stack
- 其childWidget 可以层叠到一起,层叠顺序:Widget越后创建,层级越靠上
- 可以控制没有定位的childWidget的布局策略
Stack({
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
- alignment
决定如何去对齐没有定位(没有使用Positioned)或部分定位的子widget。所谓部分定位,在这里特指没有在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位 - textDirection
和Row、Wrap的textDirection功能一样,都用于决定alignment对齐的参考系即:textDirection的值为TextDirection.ltr,则alignment的start代表左,end代表右;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左。 - fit
此参数用于决定没有定位的子widget如何去适应Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示扩伸到Stack的大小。 - overflow
此属性决定如何显示超出Stack显示空间的子widget,值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会。
IndexedStack
继承自Stack,表示只显示第几个widget,其他隐藏
Positioned
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
- left、right、bottom、top分别表示 距离stack的边的距离
- width、height表示宽高。Widget在指定left与width后,就自动确定了right。如果在设置right,则报错。其他情况(指定top与height,不能再指定bottom等)类似。
- 只能在Stack 的childs中使用。目前测试,在其他的Widget中使用会报错。
实现点赞
整体代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
//ctrl+alt+w抽取新的widget
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedModeBanner: false, home: HomePage());
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('注册'),
),
body: MyHomeBody(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
),
);
}
}
class MyHomeBody extends StatefulWidget {
@override
_MyHomeBodyState createState() => _MyHomeBodyState();
}
class _MyHomeBodyState extends State<MyHomeBody> {
var n = false;
@override
Widget build(BuildContext context) {
return Container(
height: 200,
child: Stack(overflow: Overflow.visible, //超出范围也可见
children: <Widget>[
Image.asset('asserts/images/校徽.jpg'),
Positioned( //内部的位置
left: 0,
right: 0,
bottom: 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8), //边距
color: Color.fromARGB(100, 0, 0, 0), //展示的颜色,第一个数据为透明度
child: Row( //行
mainAxisAlignment: MainAxisAlignment.spaceBetween, //between表示在两端
children: <Widget>[
Text("校徽"),
IconButton(
icon: Icon(Icons.favorite, color: n?Colors.red:Colors.white), //也可以写成函数
onPressed: (){
setState(() {
n=!n; //更改状态,重建build
});
},
)
],
)),
)
]),
);
}
}
实现效果

其实flutter还有很多好看的效果,但是属性数目很多。还需要再研究。
