How to create horizontal scrollable GridView as shown below and change Container(GridTile)'s size dynamically based on Text?

Viewed 94

enter image description here

List fu = [
    'Packing & Unpacking',
    'Cleaning',
    'Painting',
    'Heavy Lifting',
    'Shopping',
    'Watching Netflix',
    'sadfdsfe eaf',
    'ewfsfeagga,' 'gegea',
    'gaegaewgv ewaggaa aweegaage',
    'safa asdfesadfv esfsdf',
    'sadfdsfe eaf',
    'ewfsfeagga,' 'gegea',
    'awfgraga wsg sfage aegea',
    'gaegaewgv ewaggaa aweegaage',
    'asdfehtrbfawefa garevaa aewf a'
  ];

Widget build(BuildContext context) {
    return Container(
      height: 120,
      margin: EdgeInsets.symmetric(horizontal: 3.5.w, vertical: 0.8.h),
      child: StaggeredGridView.countBuilder(
        crossAxisCount: 2,
        staggeredTileBuilder: (index) => const StaggeredTile.fit(1),
        shrinkWrap: true,
        controller: _controller,
        scrollDirection: Axis.horizontal,
        // crossAxisSpacing: 0,
        mainAxisSpacing: 8,
        itemBuilder: (ctx, index) {
          return Container(
            padding: const EdgeInsets.all(15),
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(15)),
            child: Text(
              fu[index],
              maxLines: 1,
            ),
          );
        },
        itemCount: fu.length,
      ),
    );
  }

StaggeredTile.fit(1) didn't work when staggeredGridiew is horizontal.

enter image description here

I also tried using Wrap but I didn't get expected outcome.

Wrap( direction: Axis.vertical, children: fu .map((title) => Container( decoration: BoxDecoration( color: ConstColors.kWhite, borderRadius: BorderRadius.circular(15)), margin: EdgeInsets.all(8), padding: const EdgeInsets.all(8), child: Row( children: [ Text(title), ], ), )) .toList(), )

The result has extra space between containers. It would be great id there was a way to get horizontal container back to back

enter image description here

2 Answers

Try Wrap

Like so:

Wrap(
  children: List.generate(
     fu.length,
     (context){
       return Container(
            padding: const EdgeInsets.all(15),
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(15)),
            child: Text(
              fu[index],
              maxLines: 1,
            ),
          );
     })
),

You can use Warp widget to solve this

final items = <String>[
  'Packing & Unpacking',
  'Cleaning',
  'Painting',
  'Heavy Lifting',
  'Shopping',
  'Watching Netflix',
  'sadfdsfe eaf',
  'ewfsfeagga,' 'gegea',
  'gaegaewgv ewaggaa aweegaage',
  'safa asdfesadfv esfsdf',
  'sadfdsfe eaf',
  'ewfsfeagga,' 'gegea',
  'awfgraga wsg sfage aegea',
  'gaegaewgv ewaggaa aweegaage',
  'asdfehtrbfawefa garevaa aewf a'
];

class Screen extends StatelessWidget {
  const Screen({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Wrap(
        children: [
          for (var item in items)
            Container(
              decoration: BoxDecoration(
                color: Colors.white10,
                border: Border.all(color: Colors.green),
                borderRadius: const BorderRadius.all(Radius.circular(5)),
              ),
              // you can change margin to increase spacing between containers
              margin: const EdgeInsets.all(3),
              padding: const EdgeInsets.all(5),
              child: Text(item),
            ),
        ],
      ),
    );
  }
}

enter image description here

Related