我该如何解决以下错误:
======== Exception caught by widgets library =======================================================
The following assertion was thrown building AnimatedBuilder(animation: AnimationController#eedf7(▶ 0.111), dirty, state: _AnimatedState#2b432):
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
When the exception was thrown, this was the stack:
#2 Interval.transformInternal (package:flutter/src/animation/curves.dart:184:12)
#3 ParametricCurve.transform (package:flutter/src/animation/curves.dart:38:12)
#4 Curve.transform (package:flutter/src/animation/curves.dart:92:18)
#5 CurvedAnimation.value (package:flutter/src/animation/animations.dart:453:24)
#6 _PizzaDetailsState._buildIngredientsWidget (package:makefood/pizza/home/pizza_order_details.dart:101:69)
...
====================================================================================================
======== Exception caught by widgets library =======================================================
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
====================================================================================================
======== Exception caught by widgets library =======================================================
The following assertion was thrown building AnimatedBuilder(animation: AnimationController#eedf7(▶ 0.334), dirty, state: _AnimatedState#2b432):
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
When the exception was thrown, this was the stack:
#2 Interval.transformInternal (package:flutter/src/animation/curves.dart:184:12)
#3 ParametricCurve.transform (package:flutter/src/animation/curves.dart:38:12)
#4 Curve.transform (package:flutter/src/animation/curves.dart:92:18)
#5 CurvedAnimation.value (package:flutter/src/animation/animations.dart:453:24)
#6 _PizzaDetailsState._buildIngredientsWidget (package:makefood/pizza/home/pizza_order_details.dart:101:69)
...
====================================================================================================
======== Exception caught by widgets library =======================================================
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
====================================================================================================
======== Exception caught by widgets library =======================================================
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
====================================================================================================
======== Exception caught by widgets library =======================================================
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
====================================================================================================
======== Exception caught by widgets library =======================================================
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
====================================================================================================
======== Exception caught by widgets library =======================================================
The following assertion was thrown building AnimatedBuilder(animation: AnimationController#eedf7(▶ 0.908), dirty, state: _AnimatedState#2b432):
'package:flutter/src/animation/curves.dart': Failed assertion: line 184 pos 12: 'end >= begin': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
AnimatedBuilder file:///Users/mahmoudalharoon/Desktop/FoodProject/makefood/lib/pizza/home/pizza_order_details.dart:331:9
When the exception was thrown, this was the stack:
#2 Interval.transformInternal (package:flutter/src/animation/curves.dart:184:12)
#3 ParametricCurve.transform (package:flutter/src/animation/curves.dart:38:12)
#4 Curve.transform (package:flutter/src/animation/curves.dart:92:18)
#5 CurvedAnimation.value (package:flutter/src/animation/animations.dart:453:24)
#6 _PizzaDetailsState._buildIngredientsWidget (package:makefood/pizza/home/pizza_order_details.dart:101:69)
...
====================================================================================================
这是错误看起来像下面的GIF
这是_buildIngredientAnimation
方法
void _buildIngredientAnimation() {
_animationList.clear();
_animationList.add(
CurvedAnimation(
curve: Interval(
0.0,
0.8,
curve: Curves.decelerate,
),
parent: _animationController,
),
);
_animationList.add(
CurvedAnimation(
curve: Interval(
0.2,
0.8,
curve: Curves.decelerate,
),
parent: _animationController),
);
_animationList.add(
CurvedAnimation(
curve: Interval(
0.4,
1.0,
curve: Curves.decelerate,
),
parent: _animationController),
);
_animationList.add(
CurvedAnimation(
curve: Interval(
1.0,
0.7,
curve: Curves.decelerate,
),
parent: _animationController),
);
_animationList.add(
CurvedAnimation(
curve: Interval(
0.3,
1.0,
curve: Curves.decelerate,
),
parent: _animationController),
);
}
这是构建 Widget 方法:
Widget _buildIngredientsWidget() {
List<Widget> elements = [];
if (_animationList.isNotEmpty) {
for (int i = 0; i < _listIngredients.length; i++) {
Ingredient ingredient = _listIngredients[i];
final ingredientWidget = Image.asset(ingredient.image, height: 40);
for (int j = 0; j < ingredient.positions.length; j++) {
final animation = _animationList[j];
final position = ingredient.positions[j];
final positionX = position.dx;
final positionY = position.dy;
if (i == _listIngredients.length - 1) {
double fromX = 0.0, fromY = 0.0;
if (j < 1) {
fromX = -_pizzaConstraints.maxWidth * (1 - animation.value);
} else if (j < 2) {
fromX = _pizzaConstraints.maxWidth * (1 - animation.value);
} else if (j < 4) {
fromY = -_pizzaConstraints.maxHeight * (1 - animation.value);
} else {
fromY = _pizzaConstraints.maxHeight * (1 - animation.value);
}
if (animation.value > 0) {
elements.add(
Transform(
transform: Matrix4.identity()
..translate(
fromX + _pizzaConstraints.maxWidth * positionX,
fromY + _pizzaConstraints.maxHeight * positionY,
),
child: ingredientWidget,
),
);
}
} else {
elements.add(
Transform(
transform: Matrix4.identity()
..translate(
_pizzaConstraints.maxWidth * positionX,
_pizzaConstraints.maxHeight * positionY,
),
child: ingredientWidget,
),
);
}
}
}
return Stack(
children: elements,
);
}
return SizedBox.fromSize();
}
这是下面的构建方法,因为我将动画构建器称为以下代码:
@override
Widget build(BuildContext context) {
return Stack(
children: [
Column(
children: [
Expanded(
child: DragTarget<Ingredient>(
onAccept: (ingredient) {
print('onAccept');
_notifierFocused.value = false;
setState(() {
_listIngredients.add(ingredient);
_total++;
});
_buildIngredientAnimation();
_animationController.forward(from: 0.0);
},
onWillAccept: (ingredient) {
print('onWillAccept');
_notifierFocused.value = true;
for (Ingredient i in _listIngredients) {
if (i.compare(ingredient)) {
return false;
}
}
return true;
},
onLeave: (ingredient) {
print('onLeave');
_notifierFocused.value = false;
},
builder: (context, list, rejects) {
return LayoutBuilder(
builder: (context, constraints) {
_pizzaConstraints = constraints;
return Center(
child: ValueListenableBuilder<bool>(
valueListenable: _notifierFocused,
builder: (context, focused, _) {
return AnimatedContainer(
duration: const Duration(milliseconds: 400),
height: focused
? constraints.maxHeight
: constraints.maxHeight - 10,
child: Stack(
children: [
Image.asset('assets/images/dish.png'),
Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset(
'assets/images/pizza-1.png'),
),
],
),
);
}),
);
},
);
},
),
),
const SizedBox(
height: 5,
),
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
return FadeTransition(
opacity: animation,
child: SlideTransition(
position: animation.drive(
Tween<Offset>(
begin: Offset(0.0, 0.0),
end: Offset(0.0, animation.value),
),
),
child: child,
),
);
},
child: Text(
'\$$_total',
// key: Key(_total.toString()),
key: UniqueKey(),
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.cyan,
),
),
)
],
),
AnimatedBuilder(
animation: _animationController,
builder: (context, _) {
return _buildIngredientsWidget();
}),
],
);
这是下面的完整代码:
import 'package:flutter/material.dart';
import 'package:makefood/pizza/ingredient.dart';
const _pizzaCartSize = 55.0;
class PizzaOrderDetails extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'New Order Pizza',
style: TextStyle(
color: Colors.cyan,
fontSize: 29,
),
),
backgroundColor: Colors.white,
elevation: 0,
actions: [
IconButton(
icon: Icon(
Icons.add_shopping_cart,
color: Colors.cyan,
),
onPressed: () {},
),
],
),
body: Stack(
children: [
Positioned.fill(
bottom: 50,
right: 10,
left: 10,
child: Card(
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
Expanded(
flex: 3,
child: _PizzaDetails(),
),
Expanded(
flex: 2,
child: _PizzaIngredients(),
),
],
),
),
),
Positioned(
height: _pizzaCartSize,
width: _pizzaCartSize,
left: MediaQuery.of(context).size.width / 2 - _pizzaCartSize / 2,
bottom: 25,
child: _PizzaCartButton(),
)
],
),
);
}
}
class _PizzaDetails extends StatefulWidget {
@override
_PizzaDetailsState createState() => _PizzaDetailsState();
}
class _PizzaDetailsState extends State<_PizzaDetails>
with SingleTickerProviderStateMixin {
final _listIngredients = List<Ingredient>();
// final _listIngredients = <Ingredient>[];
AnimationController _animationController;
int _total = 15;
final _notifierFocused = ValueNotifier(false);
List<Animation> _animationList = <Animation>[];
BoxConstraints _pizzaConstraints;
Widget _buildIngredientsWidget() {
List<Widget> elements = [];
if (_animationList.isNotEmpty) {
for (int i = 0; i < _listIngredients.length; i++) {
Ingredient ingredient = _listIngredients[i];
final ingredientWidget = Image.asset(ingredient.image, height: 40);
for (int j = 0; j < ingredient.positions.length; j++) {
final animation = _animationList[j];
final position = ingredient.positions[j];
final positionX = position.dx;
final positionY = position.dy;
double fromX = 0.0, fromY = 0.0;
if (j < 1) {
fromX = -_pizzaConstraints.maxWidth * (1 - animation.value);
} else if (j < 2) {
fromX = _pizzaConstraints.maxWidth * (1 - animation.value);
} else if (j < 4) {
fromY = -_pizzaConstraints.maxHeight * (1 - animation.value);
} else {
fromY = _pizzaConstraints.maxHeight * (1 - animation.value);
}
elements.add(
Transform(
transform: Matrix4.identity()
..translate(
fromX + _pizzaConstraints.maxWidth * positionX,
fromY + _pizzaConstraints.maxHeight * positionY,
),
child: ingredientWidget,
),
);
}
}
return Stack(
children: elements,
);
}
return SizedBox.fromSize();
}
void _buildIngredientAnimation() {
_animationList.clear();
_animationList.add(CurvedAnimation(
curve: Interval(0.0, 0.8, curve: Curves.decelerate),
parent: _animationController,
));
_animationList.add(CurvedAnimation(
curve: Interval(0.2, 0.8, curve: Curves.decelerate),
parent: _animationController,
));
_animationList.add(CurvedAnimation(
curve: Interval(0.4, 1.0, curve: Curves.decelerate),
parent: _animationController,
));
_animationList.add(CurvedAnimation(
curve: Interval(1.0, 0.7, curve: Curves.decelerate),
parent: _animationController,
));
_animationList.add(CurvedAnimation(
curve: Interval(0.3, 1.0, curve: Curves.decelerate),
parent: _animationController,
));
}
@override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 900),
);
super.initState();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Column(
children: [
Expanded(
child: DragTarget<Ingredient>(
onAccept: (ingredient) {
print('onAccept');
_notifierFocused.value = false;
setState(() {
_listIngredients.add(ingredient);
_total++;
});
_buildIngredientAnimation();
_animationController.forward(from: 0.0);
},
onWillAccept: (ingredient) {
print('onWillAccept');
_notifierFocused.value = true;
for (Ingredient i in _listIngredients) {
if (i.compare(ingredient)) {
return false;
}
}
return true;
},
onLeave: (ingredient) {
print('onLeave');
_notifierFocused.value = false;
},
builder: (context, list, rejects) {
return LayoutBuilder(
builder: (context, constraints) {
_pizzaConstraints = constraints;
return Center(
child: ValueListenableBuilder<bool>(
valueListenable: _notifierFocused,
builder: (context, focused, _) {
return AnimatedContainer(
duration: const Duration(milliseconds: 400),
height: focused
? constraints.maxHeight
: constraints.maxHeight - 10,
child: Stack(
children: [
Image.asset('assets/images/dish.png'),
Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset(
'assets/images/pizza-1.png'),
),
],
),
);
}),
);
},
);
},
),
),
const SizedBox(
height: 5,
),
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
// layoutBuilder: (Widget currentChild, List<Widget> previousChildren) {
transitionBuilder: (child, animation) {
return FadeTransition(
opacity: animation,
child: SlideTransition(
position: animation.drive(
Tween<Offset>(
begin: Offset(0.0, 0.0),
end: Offset(0.0, animation.value),
),
),
child: child,
),
);
},
child: Text(
'\$$_total',
// key: Key(_total.toString()),
key: UniqueKey(),
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.cyan,
),
),
)
],
),
AnimatedBuilder(
animation: _animationController,
builder: (context, child) {
return _buildIngredientsWidget();
}),
],
);
}
}
class _PizzaCartButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.cyan.withOpacity(0.5),
Colors.cyan,
],
),
),
child: Icon(
Icons.shopping_bag_outlined,
color: Colors.white,
size: 35,
),
);
}
}
class _PizzaIngredients extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: ingredients.length,
itemBuilder: (context, index) {
final ingredient = ingredients[index];
return _PizzaIngredientItem(ingredient: ingredient);
},
);
}
}
class _PizzaIngredientItem extends StatelessWidget {
const _PizzaIngredientItem({Key key, this.ingredient}) : super(key: key);
final Ingredient ingredient;
@override
Widget build(BuildContext context) {
final child = Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
color: Color(0xFFF5EED3),
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Image.asset(
ingredient.image,
fit: BoxFit.contain,
),
),
),
);
return Center(
child: Draggable(
feedback: DecoratedBox(
decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
BoxShadow(
blurRadius: 10.0,
color: Colors.black26,
offset: Offset(0.0, 5.0),
spreadRadius: 10.0,
),
]),
child: child,
),
data: ingredient,
child: child,
),
);
}
}
这里还有成分类:
import 'package:flutter/rendering.dart';
class Ingredient {
const Ingredient(this.image, this.positions);
final String image;
final List<Offset> positions;
bool compare(Ingredient ingredient) => ingredient.image == image;
}
final ingredients = const <Ingredient>[
Ingredient(
'assets/images/chili.png',
<Offset>[
Offset(0.2, 0.2),
Offset(0.6, 0.2),
Offset(0.4, 0.25),
Offset(0.5, 0.3),
Offset(0.4, 0.65),
],
),
Ingredient(
'assets/images/garlic.png',
<Offset>[
Offset(0.2, 0.35),
Offset(0.65, 0.35),
Offset(0.3, 0.23),
Offset(0.5, 0.2),
Offset(0.3, 0.5),
],
),
Ingredient(
'assets/images/olive.png',
<Offset>[
Offset(0.25, 0.5),
Offset(0.65, 0.6),
Offset(0.2, 0.3),
Offset(0.4, 0.2),
Offset(0.2, 0.6),
],
),
Ingredient(
'assets/images/onion.png',
<Offset>[
Offset(0.2, 0.65),
Offset(0.65, 0.3),
Offset(0.25, 0.25),
Offset(0.45, 0.35),
Offset(0.4, 0.65),
],
),
Ingredient(
'assets/images/pea.png',
<Offset>[
Offset(0.2, 0.35),
Offset(0.65, 0.35),
Offset(0.3, 0.23),
Offset(0.5, 0.2),
Offset(0.3, 0.5),
],
),
Ingredient(
'assets/images/pickle.png',
<Offset>[
Offset(0.2, 0.65),
Offset(0.65, 0.3),
Offset(0.25, 0.25),
Offset(0.45, 0.35),
Offset(0.4, 0.65),
],
),
Ingredient(
'assets/images/potato.png',
<Offset>[
Offset(0.2, 0.2),
Offset(0.6, 0.2),
Offset(0.4, 0.25),
Offset(0.5, 0.3),
Offset(0.4, 0.65),
],
),
];
答案 0 :(得分:1)
_animationList.add(
CurvedAnimation(
curve: Interval(
1.0,
0.7,
curve: Curves.decelerate,
),
parent: _animationController),
);
看这段代码行,区间从 1.0 开始,到 0.7 结束。结束应始终大于开始。我遇到了同样的错误 :) 希望这会有所帮助。