What is the best way to implement the following ListView with the corner edge in Flutter?
Since I need overlapping on the rounded corner, is there a certain implementation using Stack and Positioned for this?
I found a way to do it without the use of Stack and Positioned.
I created a ListView using the ListView.builder() with each row being two container (parent and child). The bottom container (parent) takes the background of the next row's colour from the array (index+1). Then I add a container with a rounded edge taking it's colour based on its index. If it was the last row, the bottom container will be transparent. This will give the result as expected.
List<Color> colours = [
Colors.red,
Colors.green,
Colors.blue,
Colors.amber,
Colors.brown,
Colors.deepPurple,
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
),
body: ListView.builder(
itemCount: colours.length,
itemBuilder: (context, index) {
return Container( // This is the back container which will show next cell colour on the rounded edge
color: index + 1 < colours.length
? colours[index + 1] // get next row background as back container background
: Colors.transparent, // Otherwise keep it transparent to prevent out of bounds error
child: Container(
height: 180,
decoration: BoxDecoration(
borderRadius:
const BorderRadius.only(bottomLeft: Radius.circular(85.0)),
color: colours[index],
),
child: Center(
child: Text(
index.toString(),
style: const TextStyle(color: Colors.white, fontSize: 50),
),
),
),
);
},
),
);
}
}
Use a stack and then calculate positions of each item.
List<Color> colorsList = [Colors.red, Colors.green, Colors.blue];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
children: colorsList.reversed
.map(
(color) => Positioned(
top: colorsList.indexOf(color).toDouble() * 60,
child: ListItem(
color: color,
text: "Animation",
onTap: _goToAnimationPage,
),
),
)
.toList(),
),
);
}
Code of the ListItem:
Widget build(BuildContext context) {
return Container(
height: 100,
width: MediaQuery.of(context).size.width,
child: Material(
color: color,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(40.0)),
child: InkWell(
onTap: onTap,
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: Text(
text,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
),
),
);
}
And the result:
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