Im trying to create a stack of cards, superimposed, and offset of each other to visualize multiple versions of a card.
I have tried putting cards inside cards, but do not find a way to offset them. I also tried using the stack class with no luck.
Anyone know how i can achieve this effect?
You were going in the right direction with Stack - you just had to figure out how to offset the widget. The best way to do this for the 'top' of the stack is to use padding, but you don't want to have to specify the size of each of the cards... it's much better if the stack grows/shrinks based on the content which is actually being shown.
To that end, you can use Positioned with all of the sizes specified for the cards. That will make sure that they grow to the appropriate size, without making the stack resize or having to specify each of their sizes.
Here's the code:
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),
),
),
);
}
Hmmm... I guess that build function could probably be explained a bit. What I'm doing is using a generated list to iterate from 0..(num cards - 1) and calculating the appropriate offsets for each Positioned widget (each of which contains an essentially empty card).
Then this gets made from an iterable to a list with .toList()
, but doesn't have the top card yet... so I do an inline add (I'm sure there's a better word for that, but I don't know it) of the Padding widget that has the appropriate offsets and contains the child. The ..add
just makes it so that I can do it in one line - it returns the list instead of void as .add
would. Yay for dart =)!
I made it a little bit flexible, but you could go further and define the offset as two parameters, make it so that you can go different directions etc. Anyways, the code results in this:
This may not be the best approach but according to the sample you posted in the comment you can align it with a Stack and Padding:
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:
You can then customize it with setting different paddings etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With