Предупреждение о переполнении в AnimatedContainer, регулирующем высоту

Пример

Используя CupertinoPicker, я хочу, чтобы он отображался под текстовым вводом, используя AnimatedContainer, но когда он становится видимым, я получаю предупреждение о переполнении. Из того, что я видел, вы не можете регулировать размер CupertinoPicker, только его родительский элемент.

Есть ли лучшее решение?

Column(
    children: <Widget>[
        buildTextField(
            field: 'limit',
            label: 'How Many Guests?',
            controller: TextEditingController(
                text: eventModel.event['limit']),
            onTap: () {
                showPicker.value = !showPicker.value;
            },
        ),
            AnimatedContainer(
            height: showPicker.value ? 150 : 0,
            duration: Duration(milliseconds: 150),
            child: showPicker.value
                ? CupertinoPicker(
                    backgroundColor: Colors.transparent,
                    itemExtent: 40,
                    children: List<Widget>.generate(
                        98,
                        (index) => Center(
                            child: Text(
                                '${index + 2}',
                                style: TextStyle(
                                    color: Colors.black,
                                    fontSize: 16),
                            ),
                            ),
                    ),
                    onSelectedItemChanged: (item) {
                        print((item + 2).toString());
                    },
                    )
                : null,
        ),
    ]
)

Исключение:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following message was thrown during layout:
flutter: A RenderFlex overflowed by 22 pixels on the bottom.
flutter:
flutter: The overflowing RenderFlex has an orientation of Axis.vertical.
flutter: The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
flutter: black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
flutter: Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
flutter: RenderFlex to fit within the available space instead of being sized to their natural size.
flutter: This is considered an error condition because it indicates that there is content that cannot be
flutter: seen. If the content is legitimately bigger than the available space, consider clipping it with a
flutter: ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
flutter: like a ListView.
flutter: The specific RenderFlex in question is:
flutter:   RenderFlex#73b9d relayoutBoundary=up16 OVERFLOWING
flutter:   creator: Column ← Stack ← CupertinoPicker ← ConstrainedBox ← Container ← AnimatedContainer ←
flutter:   Column ← Observer ← _FormScope ← WillPopScope ← Form ← Padding ← ⋯
flutter:   parentData: not positioned; offset=Offset(0.0, 0.0) (can use size)
flutter:   constraints: BoxConstraints(0.0<=w<=346.9, 0.0<=h<=18.2)
flutter:   size: Size(346.9, 18.2)
flutter:   direction: vertical
flutter:   mainAxisAlignment: start
flutter:   mainAxisSize: max
flutter:   crossAxisAlignment: center
flutter:   verticalDirection: down
flutter: ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
flutter: Another exception was thrown: A RenderFlex overflowed by 22 pixels on the bottom.

person Anthony Urbina    schedule 24.05.2019    source источник


Ответы (2)


Проблема с AnimatedContainer и CupertinoPicker, потому что для детей itemExtent: 40 используется фиксированная высота.

Попробуйте использовать SizeTransition для достижения того же эффекта. Это образец:

    class _MySampleWidgetState extends State<MySampleWidget>
        with SingleTickerProviderStateMixin {
      bool showPicker = false;
      AnimationController _controller;

      @override
      void initState() {
        _controller = AnimationController(
          vsync: this,
          duration: Duration(milliseconds: 200),
        );
        super.initState();
      }

      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                child: Text("text"),
                onPressed: () {
                  showPicker = !showPicker;
                  if (showPicker) {
                    _controller.forward();
                  } else {
                    _controller.reverse();
                  }
                },
              ),
              SizeTransition(
                sizeFactor: _controller,
                child: Container(
                  height: 150,
                  child: CupertinoPicker(
                    backgroundColor: Colors.transparent,
                    itemExtent: 40,
                    children: List<Widget>.generate(
                        98,
                        (index) => Center(
                              child: Text(
                                '${index + 2}',
                                style: TextStyle(color: Colors.black, fontSize: 16),
                              ),
                            )),
                    onSelectedItemChanged: (item) {
                      print((item + 2).toString());
                    },
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
person diegoveloper    schedule 24.05.2019
comment
Вау, что получилось! Спасибо! Мне нравится сталкиваться с этими проблемами, потому что есть ОЧЕНЬ много виджетов, которые можно использовать для того же. Но не все способы оптимальны. Спасибо! - person Anthony Urbina; 24.05.2019

Вы можете заключить в оболочку свои другие виджеты с помощью SingleChildScrollView следующим образом:

AnimatedContainer( 
duration:Duration(milliseconds:500),
    child: SingleChildScrollView(child:contents),
),
person Viand Direct    schedule 11.03.2021