Flutter multiple items in Row with Expanded/Flexible

Issue

I want to have more(in this example 4) items in Row. I tried use Expanded or Flexible or mainAxisAlignment: MainAxisAlignment.spaceEvenly to fill up all width of screen. But I want to heve items lets say specific width and height 50 pixels, and GestureDetector which is around item to be 1/4 of screen(4 items = full width). So everywhere I tap in the row something will be selected. My problem is that every my solution deforms items(circles) or circle must be very huge to width = height to not be deformed.
I also tried wrapping whole _ratingEmoji in Expanded and giving ratingItem.ratingIndicator constraints to max width but with same result.

Row of items:

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    for (var ratingItem in editGroceryRatingProvider.foodRatings)
      _ratingEmoji(editGroceryRatingProvider, ratingItem, context),
  ],
),

Item:

Widget _ratingEmoji(EditGroceryRatingProvider editGroceryRatingProvider,
  SelectedFoodRating ratingItem, BuildContext context) {
return GestureDetector(
  child: ratingItem.selected
      ? Container(
          width: MediaQuery.of(context).size.width / 8,
          height: MediaQuery.of(context).size.width / 8,
          padding: const EdgeInsets.all(2.0),
          decoration: BoxDecoration(
              border: Border.all(
                color: Color(0xFF312ADB),
                width: 3.0,
              ),
              borderRadius: BorderRadius.circular(32.0)),
          child: Center(
            child: ratingItem.ratingIndicator,
          ),
        )
      : ratingItem.ratingIndicator,
  onTap: () => editGroceryRatingProvider.updateSelectedRating(ratingItem),
);

}

RatingIndicator which is "circle" item to be on the screen:

Container(
  decoration: BoxDecoration(
    border: Border.all(
      color: color,
      width: 1.5,
    ),
    borderRadius: BorderRadius.circular(64.0),
  ),
  child: Container(
    decoration: BoxDecoration(
      border: Border.all(
        color: Colors.white,
        width: 3.0,
      ),
      borderRadius: BorderRadius.circular(64.0),
    ),
    child: ClipOval(
      child: Container(
        width: width ?? MediaQuery.of(context).size.width / 7,
        height: height ?? MediaQuery.of(context).size.width / 7,
        color: color,
      ),
    ),
  ),
);

Thanks a lot.

Update:

row with items

Items should stay as they are on screenshot, but "whole" row should be clickable(means even if you click between 2 items, one closer to click should be selected)

Solution

Check, please solution.
The whole area is clickable. You just need to add your item instead of mine.

row with items

@override
  Widget build(BuildContext context) {
    final colors = [Colors.red, Colors.blue, Colors.brown, Colors.cyan];
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        color: const Color(0xffFAFAFA),
        child: Row(
          children: List.generate(
              colors.length,
              (index) => Expanded(
                    child: GestureDetector(
                        onTap: () => print('Tapped:$index'),
                        child: Container(
                          height: 50,
                          color: Colors.transparent,
                          child: Container(
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: colors[index],
                            ),
                          ),
                        )),
                  )),
        ),
      ),
    );

Answered By – Yauhen Sampir

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *