Flutter: как по-разному выровнять два элемента в столбце

У меня есть такая колонка с флаттером:

Container(
      width: width,
      height: width,
      decoration: BoxDecoration(
        color: Theme.of(context).primaryColor,
        borderRadius: BorderRadius.circular(10),
      ),
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            FittedBox(child: Icon(Icons.cancel, size: 40)),
            FittedBox(child: Text("data")),
          ],
        ),
      ),
    );

Но я хочу, чтобы Icon был точно по центру, а текст был выровнен по дну оранжевого контейнера. Есть ли способ сделать это без использования стека? Как вы можете видеть на изображении ниже, и значок, и текст выровнены по центру, поэтому значок не идеально отцентрирован.

Flutter: как по-разному выровнять два элемента в столбце

Спасибо за вашу помощь.

"Есть ли способ сделать это без использования стека?" - да, CustomMultiChildLayout
pskink 29.03.2022 11:21

Почему бы не использовать стек?

Rukka 29.03.2022 11:21

Можете ли вы сказать, кроме дизайна?

Ravindra S. Patil 29.03.2022 11:23

Стек — лучший способ для вашего варианта использования.

Arijeet 29.03.2022 11:30

@Rukka Потому что я знаю, как это сделать со стеком, но мне было интересно, можно ли сделать это проще, например, с параметром, специфичным для столбца, или чем-то в этом роде. Но я думаю, что буду использовать стек, потому что похоже, что pskink ответ возможен, но его сложнее реализовать, чем стек.

Simon B 29.03.2022 11:30

@SimonB с Stack вы не можете выровнять верх текста по низу значков, как показано на изображении, которое вы разместили (вы можете выровнять низ текста только по низу всего оранжевого контейнера) - однако это можно сделать с CustomMultiChildLayout

pskink 29.03.2022 17:56

это пример делегата: class _Delegate extends MultiChildLayoutDelegate { @override void performLayout(ui.Size size) { Rect r = Offset.zero & size; final iconS = layoutChild(0, BoxConstraints.loose(size)); final iconR = Alignment.center.inscribe(iconS, r); positionChild(0, iconR.topLeft); r = Rect.fromLTRB(0, iconR.bottom, r.right, r.bottom); final labelS = layoutChild(1, BoxConstraints.loose(r.size)); final labelR = Alignment.topCenter.inscribe(labelS, r); positionChild(1, labelR.topLeft); } @override bool shouldRelayout(covariant MultiChildLayoutDelegate old) => false; }

pskink 05.04.2022 16:20
1
7
105
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Выравнивание widget может помочь. Позвольте вашему Column принять максимальную высоту (определяемую родителем Container) и оберните значок Expanded или Flexible, затем оберните ваши элементы Align с соответствующими значениями выравнивания.

Кстати, это не обеспечивает центрирование идеально, но приближается к нему настолько, насколько мал ваш текст.

Container(
    width: width,
    height: width,
    decoration: BoxDecoration(
      color: Colors.amber,
      borderRadius: BorderRadius.circular(10),
    ),
    child: Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Flexible(
            child: Align(
                alignment: Alignment.center,
                child: Icon(Icons.cancel, size: 40))),
        Align(alignment: Alignment.bottomCenter, child: Text("data")),
      ],
    ),
  );

Попробуй это

Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
      color: Theme.of(context).primaryColor,
      borderRadius: BorderRadius.circular(10),
    ),
    child: Column(
      children: [
        Expanded(child: Container()),
        Expanded(
            child: Center(
                child: FittedBox(child: Icon(Icons.cancel, size: 40)))),
        Expanded(
            child: Align(
          alignment: Alignment.bottomCenter,
          child: FittedBox(
              child: Text(
            "data",
            style: TextStyle(fontSize: 25),
          )),
        )),
      ],
    ),
  ),

Спасибо, это умно, но этот код не такой уж "чистый". Но спасибо за ваш ответ.

Simon B 29.03.2022 13:44

Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, редактировать добавьте дополнительную информацию, например цитаты или документацию, чтобы другие могли подтвердить правильность вашего ответа. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.

Community 29.03.2022 14:39
Ответ принят как подходящий

В конце концов я решил использовать стек, потому что на самом деле это был самый простой способ сделать то, что я хотел сделать... Вот как я это сделал:

SizedBox(
          width: width,
          height: width,
          child: Stack(
            children: [
              Align(
                  alignment: Alignment.center,
                  child: FittedBox(
                    fit: BoxFit.scaleDown,
                      child: Icon(Icons.cancel, size: 40))),
              Align(
                  alignment: Alignment.bottomCenter,
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 5.0, vertical: 3),
                    child: FittedBox(
                        fit: BoxFit.scaleDown,
                        child: Text(
                          "data",
                        )),
                  )),
            ],
          ),
        ),

Со стеком и выравниванием это соответствует тому, что я хотел сделать... Спасибо за помощь всем, кто ответил на этот пост.

Другие вопросы по теме