使用Stack是正确的做法,只需要找到如何对部件进行偏移即可。对于堆栈的“顶部”,最好的方法是使用填充(padding),但您不希望指定每个卡的大小……如果堆栈可以根据实际显示的内容增长/缩小,那就更好了。
为此,您可以在所有卡的大小都指定的情况下使用Positioned。这将确保它们按适当的大小增长,而无需使堆栈调整大小或指定每个卡的大小。
以下是代码:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Container(
color: Colors.grey,
child: ListView(
children: [
StackOfCards(
child: Container(height: 100.0),
num: 5,
),
StackOfCards(
child: Container(height: 100.0),
num: 4,
),
StackOfCards(
child: Container(height: 100.0),
num: 3,
),
StackOfCards(
child: Container(height: 100.0),
num: 2,
),
StackOfCards(
child: Container(height: 100.0),
num: 1,
)
\],
),
),
),
);
}
}
class StackOfCards extends StatelessWidget {
final int num;
final Widget child;
final double offset;
const StackOfCards({Key key, int num = 1, @required this.child, this.offset = 10.0})
: this.num = num > 0 ? num : 1,
assert(offset != null),
super(key: key);
@override
Widget build(BuildContext context) => Stack(
children: List<Widget>.generate(
num - 1,
(val) => Positioned(
bottom: val * offset,
left: val * offset,
top: (num - val - 1) * offset,
right: (num - val - 1) * offset,
child: Card(child: Container()))).toList()
..add(
Padding(
child: Card(child: child),
padding: EdgeInsets.only(bottom: (num - 1) * offset, left: (num - 1) * offset),
),
),
);
}
嗯...我想那个构建函数可能需要解释一下。我的做法是使用生成的列表迭代从0..(卡片数-1),并为每个定位小部件计算适当的偏移量(每个小部件包含一个基本上为空的卡片)。
然后将其从可迭代转换为列表使用.toList()
,但还没有顶部的卡片...所以我进行内联添加(我确定有更好的词来描述,但我不知道是什么)具有适当偏移量和包含子元素的Padding小部件。 ..add
只是使它可以在一行中完成-它返回列表而不是void,就像.add
一样。感谢dart =)!
我让它有点灵活,但您可以进一步定义偏移量作为两个参数,使其可以朝不同方向等。无论如何,代码的结果如下:
Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
child: Card(
child: Center(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Text("Content"),
),
)),
),
Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 8.0),
child: Card(
child: Center(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Text("Content"),
),
)),
),
],
)
Which will look like this:
你可以使用不同的填充等来自定义它。