Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView with Rounded Edges

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?

enter image description here

like image 758
Assim Avatar asked Jan 01 '23 21:01

Assim


2 Answers

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),
                  ),
                ),
              ),
           );
        },
      ),
    );
  }
}

enter image description here

like image 147
Assim Avatar answered Feb 05 '23 23:02

Assim


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:

enter image description here

like image 40
Sergio Bernal Avatar answered Feb 06 '23 01:02

Sergio Bernal