Перемещайте несколько элементов в ряд с расширенным / гибким

Я хочу иметь больше (в этом примере 4) элементов в строке. Я пробовал использовать Expanded или Flexible или mainAxisAlignment: MainAxisAlignment.spaceEvenly, чтобы заполнить всю ширину экрана. Но я хочу, чтобы элементы, скажем, определенная ширина и высота 50 пикселей, и GestureDetector, который находится вокруг элемента, занимают 1/4 экрана (4 элемента = полная ширина). Итак, везде, где я нажимаю в строке, что-то будет выделено. Моя проблема в том, что каждое мое решение деформирует элементы (круги) или круг должен быть очень большим до ширины = высоты, чтобы не деформироваться. Я также попытался обернуть весь _ratingEmoji в Expanded и установить ограничения ratingItem.ratingIndicator на максимальную ширину, но с тем же результатом.

Ряд предметов:

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

Пункт:

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 - элемент "кружок", который должен отображаться на экране:

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

Большое спасибо.

Обновить:

Элементы должны оставаться такими, как на скриншоте, но "вся" строка должна быть интерактивной (это означает, что даже если вы щелкаете между двумя элементами, должен быть выбран один ближе к щелчку)

1 ответ

Решение

Проверьте, пожалуйста, решение. Вся область кликабельна. Вам просто нужно добавить свой предмет вместо моего.

@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],
                            ),
                          ),
                        )),
                  )),
        ),
      ),
    );
Другие вопросы по тегам