skip to Main Content

I’m trying to create a custom border with a dynamic size and a gradient color on it.

How can I create a border with the same width as the text above?

@override
Widget build(BuildContext context) {
var selectedItemIndex = 0;

return SingleChildScrollView(
  scrollDirection: Axis.horizontal,
  child: Wrap(
    spacing: 32,
    children: list.asMap().entries.map((entry) {
      var isSelectedItem = (entry.key == selectedItemIndex);
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            entry.value,
            style: TextStyle(
              fontSize: 16,
              color:
                  entry.key == selectedItemIndex ? Colors.white : lightGrey,
            ),
          ),
          const SizedBox(
            height: 4,
          ),
          Flex(
            direction: Axis.horizontal,
            children: [
              Container(
                height: isSelectedItem ? 3 : 2,
                width: 40,  // <- fixed size
                decoration: const BoxDecoration(
                  gradient: purpleGradient,
                ),
              ),
            ],
          ),
        ],
      );
    }).toList(),
  ),
);

}

enter image description here

ps.: I tried Flex, Flexible, and double.infinity to expand the border’s width.

2

Answers


  1. See https://medium.com/vijay-r/neon-light-effect-flutter-23a36c341fe7 will help you,
    For dynamic size Try setting mainAxisSize: MainAxisSize.min on the column and adding some spacing.

    Login or Signup to reply.
  2. Try this:

    custom button:

    class UnderlineButton extends StatelessWidget {
      final String label;
      final Function onTap;
    
      const UnderlineButton({
        Key? key,
        required this.label,
        required this.onTap,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return TextButton(
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
            ),
            overlayColor: MaterialStateProperty.all<Color?>(Colors.transparent),
          ),
          onPressed: onTap,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(label),
              Container(
                height: 7,
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.bottomLeft,
                    end: Alignment.bottomRight,
                    colors: [
                      Colors.blue,
                      Colors.indigo,
                    ],
                    tileMode: TileMode.repeated,
                  ),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(label, style: const TextStyle(color: Colors.transparent),),
                  ],
                ),
              ),
            ],
          ),
        );
      }
    }
    

    use custom button in screen:

    class TestScreen extends StatelessWidget {
      const TestScreen({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Row(
              children: [
                UnderlineButton(
                  label: 'Recent',
                  onTap: () {},
                ),
                UnderlineButton(
                  label: 'Top 50',
                  onTap: () {},
                ),
                UnderlineButton(
                  label: 'Festival',
                  onTap: () {},
                ),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search