Вы шли в правильном направлении со стеком - вам просто нужно было выяснить, как компенсировать виджет. Лучший способ сделать это для «верха» стопки - использовать заполнение, но вам не нужно указывать размер каждой из карточек ... гораздо лучше, если стопка увеличивается / уменьшается на основе контент, который на самом деле показывается.
Для этого вы можете использовать Позиционирование со всеми размерами, указанными для карт. Это обеспечит их рост до нужного размера без изменения размера стека или указания каждого их размера.
Вот код:
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 .. (num cards - 1) и вычисляю соответствующие смещения для каждого позиционированного виджета (каждый из которых содержит практически пустую карту).
Затем это делается из итерируемого в список с .toList()
, но пока нет верхней карты ... поэтому я делаю встроенное добавление (я уверен, что есть лучшее слово для этого, но я не знаю) виджета Padding, который имеет соответствующие смещения и содержит дочерний элемент. ..add
просто делает так, что я могу сделать это в одной строке - он возвращает список вместо void, как .add
. Уя за дротик =)!
Я сделал его немного гибким, но вы можете пойти дальше и определить смещение как два параметра, сделать так, чтобы вы могли идти в разных направлениях и т. Д. В любом случае, код приводит к следующему: