Stack
和 Positioned
来实现这个效果:
class StackExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: new Container(
padding: const EdgeInsets.all(8.0),
height: 500.0,
width: 500.0,
// alignment: FractionalOffset.center,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
new Positioned(
left: 20.0,
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
),
new Positioned(
left:40.0,
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
)
],
),
),
)
;
}
}
以下是一种方法,可以让图标投下阴影,让它更加突出:
class StackExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: new Container(
padding: const EdgeInsets.all(8.0),
height: 500.0,
width: 500.0,
// alignment: FractionalOffset.center,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
),
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
new Positioned(
left: 20.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
),
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
),
new Positioned(
left:40.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
)
,child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
)
],
),
),
)
;
}
}
截至2019年11月,我想添加第二个解决方案:
使用软件包:https://pub.dev/packages/assorted_layout_widgets
var widget1 = ...;
var widget2 = ...;
RowSuper(
children: [widget1, widget2],
innerDistance: -20.0,
);
这将使行单元格重叠20像素。
与使用Stack
的解决方案不同之处在于,Stack
中的Positioned
小部件不占用空间。因此,除非您预先知道其大小,否则不能使Stack
成为其内容的大小。然而,RowSuper
将具有其所有子小部件的大小。
请注意,还有一个ColumnSuper
。还要注意我是这个包的作者。
我希望找到一个没有依赖关系和固定布局的东西。 你可以通过使用媒体查询来以百分比方式重叠,从而增强效果。
Widget overlapped() {
final overlap = 10.0;
final items = [
CircleAvatar(child: Text('1'), backgroundColor: Colors.red),
CircleAvatar(child: Text('2'), backgroundColor: Colors.green),
CircleAvatar(child: Text('3'), backgroundColor: Colors.blue),
];
List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
return Padding(
padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
child: items[index],
);
});
return Stack(children: stackLayers);
}
Row
(或Column
和Flex
)完全相同。但它还允许您设置负间距,从而导致其子项重叠。您还可以设置哪些子项在重叠时应位于顶部。SignedSpacingRow(
spacing: -12.0,
stackingOrder: StackingOrder.lastOnTop,
children: <Widget>[
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
],
),
如果需要,它也可以与扩展的子元素一起使用。
OverflowBox
包装元素,并赋予maxWidth
值,可以实现此效果。 return SizedBox(
width: 35, //--> list children will be 35 in width
child: OverflowBox(
maxWidth: 50, // --> allowing the child to overflow will cause overlap between elements
child: Container(
width: 50,
child: Text((index + 1).toString()),
),
),
);
基于@Lee Higgins的反转变体
const size = 32.0;
const overlap = size - 6.0;
final containers = [
Container(
decoration: BoxDecoration(
color: Colors.grey[300],
shape: BoxShape.circle,
),
width: size,
height: size,
),
Container(
decoration: BoxDecoration(
color: Colors.grey[400],
shape: BoxShape.circle,
),
width: size,
height: size,
),
];
List<Widget> stackLayers = List<Widget>.generate(containers.length, (index) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 0, index * overlap, 0),
child: containers[index],
);
});
return Stack(alignment: AlignmentDirectional.topEnd, children: stackLayers);
以下是我在Flutter中实现头像和相机图像重叠的代码。
输出结果: 点击此处查看输出图片
Container(
constraints: new BoxConstraints(
maxHeight: 200.0,
maxWidth: 200.0
),
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0),
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
image: new AssetImage('assets/images/profile.png'),
fit: BoxFit.cover,
),
),
child: Stack(
children: [
new Positioned(
right: 0.0,
bottom: 3.0,
child: Container(
constraints: new BoxConstraints(
maxHeight: 50.0,
maxWidth: 50.0
),
decoration: new BoxDecoration(
boxShadow: [
BoxShadow(
color:Color(0xFFdedede),
offset: Offset(2,2)
),
],
color: Colors.white,
shape: BoxShape.circle,
),
child: GestureDetector(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.photo_camera,
size: 34,
color: Color(0xFF00cde7),
),
),
),
),
),
],
),
)
Stack(
children: [
Padding(
padding: const EdgeInsets.only(left: 40),
child: Image.asset('assets/icons/avatar3.png'),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Image.asset('assets/icons/avatar2.png'),
),
Padding(
padding: const EdgeInsets.only(left: 0),
child: Image.asset('assets/icons/avatar1.png'),
),
],
)
new Center(child: new StackExample())
- Raouf Rahichealignment: FractionalOffset.center
时,它会居中但被其他元素溢出。 - Shady AzizaPositioned.fromRelativeRect
。 - Raouf Rahicheoverflow: Overflow.visible
。 - Shady Aziza