Search code examples
flutterborderlisttile

Column of Listtile with rounded corner at beginning and end


I'm trying to have a column of list tiles where the top and bottom corners are rounded. Some tiles change colors when hovered and other don't. Hence, I have tried to two things:

  • Create a container with rounded corners, add a Column inside with my listTiles.
  • Create a column with my list tiles, and add specific rounded countainers for the first and last element.
  • Color the container that hold all elements. The problem then is that the hover color of the listtiles is painted under that of the container.

Sadly, in both cases, the background color of the list tile overflow from the rounded container as seen in this image:

Example result

Here is the sample code for the second try:

import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  final children = List<Widget>.generate(
      5,
      (i) => ListTile(
          tileColor: Colors.green, hoverColor: Colors.red, title: Text('$i')));

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: List.generate(
        children.length,
        (index) {
          if (index == 0 && index == children.length - 1) {
            return Ink(
              // clipBehavior: Clip.antiAlias,
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.red,
                ),
                borderRadius: BorderRadius.circular(20),
                color: Colors.blue,
              ),
              child: children[index],
            );
          }
          if (index == 0) {
            return Container(
              clipBehavior: Clip.antiAlias,
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.red,
                ),
                borderRadius: const BorderRadius.only(
                    topLeft: Radius.circular(20),
                    topRight: Radius.circular(20)),
                color: Colors.blue,
              ),
              child: children[index],
            );
          } else if (index == children.length - 1) {
            return Container(
              clipBehavior: Clip.antiAlias,
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.red,
                ),
                borderRadius: const BorderRadius.only(
                    bottomLeft: Radius.circular(20),
                    bottomRight: Radius.circular(20)),
                color: Colors.blue,
              ),
              child: children[index],
            );
          }

          return children[index];
        },
      ),
    );
  }
}

Where children is a list of listile and other elements.

How can a force element in children to respect the border limits set up by the parent container?


Solution

  • I have ended-up posting an Issue on Github.

    The solution a Card with clipBehavior: Clip.antiAlias.