BoxConstraints has a negative minimum width

Viewed 9550

in this class as an widget which i use animation to show and hide, when i multiple show or hiding by click, sometimes i get this error:

BoxConstraints has a negative minimum width.The offending constraints were: BoxConstraints(w=-0.8, 0.0<=h<=Infinity; NOT NORMALIZED)

this part of code has problem

child: Row( //<--- problem cause on this line of code
   children: <Widget>[
      ...
   ],
),

My class code:

class FollowingsStoryList extends StatefulWidget {
  final List<Stories> _stories;

  FollowingsStoryList({@required List<Stories> stories}) : _stories = stories;

  @override
  _FollowingsStoryListState createState() => _FollowingsStoryListState();
}

class _FollowingsStoryListState extends State<FollowingsStoryList> with TickerProviderStateMixin {
  List<Stories> get stories => widget._stories;
  bool _isExpanded = false;
  AnimationController _barrierController;

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

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      curve: _isExpanded ? Curves.elasticOut : Curves.elasticIn,
      duration: Duration(milliseconds: 800),
      child: Row(
        children: <Widget>[
          AnimatedContainer(
            curve: _isExpanded ? Curves.elasticOut : Curves.elasticIn,
            duration: Duration(milliseconds: 800),
            width: _isExpanded ? 90 : 1,
            color: Colors.white,
            padding: EdgeInsets.only(bottom: 65.0),
            child: Column(
              children: <Widget>[
              ],
            ),
          ),
          GestureDetector(
            onTap: _toggleExpanded,
            child: StoriesShapeBorder(
              alignment: Alignment(1, 0.60),
              icon: Icons.adjust,
              color: Colors.white,
              barWidth: 4,
            ),
          ),
        ],
      ),
    );
  }

  _toggleExpanded() {
    setState(() {
      _isExpanded = !_isExpanded;
      if (_isExpanded) {
        _barrierController.forward();
      } else {
        _barrierController.reverse();
      }
    });
  }
}
2 Answers

Because Curves.elasticOut and Curves.elasticIn are

oscillating curves that grows/shrinks in magnitude while overshooting its bounds.

When _isExpanded is false, you are expecting the width to go from 90 to 1 however Curves.elasticOut overshoots and becomes much less than 1 (hence a negative width) for a short period of time.

This is what is causing the error imho. Plus for what reason do you have nested AnimatedContainers? Top AnimatedContainer seems unnecessary.

Try getting rid of the top AnimatedContainer and changing all 4 of the Curves to Curves.linear and I think your error will be gone. Actually you can use any Curves which don't overshoot.

If you really need Elastic Curve, then maybe this would work too:

@override
  Widget build(BuildContext context) {
    return Row(
        children: <Widget>[
          AnimatedContainer(
            curve: _isExpanded ? Curves.elasticOut : Curves.easeInSine,
            duration: Duration(milliseconds: 800),
            width: _isExpanded ? 90 : 1,
            color: Colors.white,
            padding: EdgeInsets.only(bottom: 65.0),
            child: Column(
              children: <Widget>[
              ],
            ),
          ),
          GestureDetector(
            onTap: _toggleExpanded,
            child: StoriesShapeBorder(
              alignment: Alignment(1, 0.60),
              icon: Icons.adjust,
              color: Colors.white,
              barWidth: 4,
            ),
         ),
       ],
    );
  }

Try it and let me know.

For example, you can use AnimatedController, to (oddly enough) control your animation value and set minimum value "0".

import 'dart:math' as math;

double getValue(...) {
  // some logic / curves
  // ....

  return math.max(0, value);
}
Related