AnimationList Flutter 中的 RangeError?
RangeError in AnimationList Flutter?
我正在做一个项目,我正在其中生成一个订单列表。每当我尝试从列表中删除一个项目。它抛出 RangeError (index): Invalid value: Only valid value is 0: 1
的异常。
但是,它会同时删除该项目。如果存在范围问题,为什么要删除该项目?或者这个错误是什么时候产生的?另一件事是如何在特定小部件中应用 try/catch?
代码如下:
class OrderList extends StatefulWidget {
@override
_OrderListState createState() => _OrderListState();
}
class _OrderListState extends State<OrderList> {
CartList cart = CartList.instance;
final GlobalKey<AnimatedListState> _key = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
elevation: 0.0,
title: Text('Orders'),
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Badge(
child: Icon(Icons.shopping_cart, color: Colors.white, size: 40),
badgeContent: Text(
cart.listLength(),
style: TextStyle(color: Colors.white),
),
badgeColor: Colors.amber,
toAnimate: true,
animationType: BadgeAnimationType.fade,
),
),
],
),
body: AnimatedList(
key: _key,
initialItemCount: cart.list.length,
itemBuilder: (context, index, animation) {
return _buildItem(cart.list[index], animation, index);
},
),
);
}
Widget _buildItem(FoodItem list, Animation<double> animation, int index) {
return SizeTransition(
sizeFactor: animation,
child: Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('assets/${cart.list[index].img}'),
),
title: Text(cart.list[index].name),
subtitle: Text(
'${cart.list[index].quantity} x ${cart.list[index].price} = ${cart.list[index].quantity * cart.list[index].price}'),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: (){
_removeItem(index);
setState(() {
});
},
),
),
),
);
}
void _removeItem(int index) {
FoodItem removeItem = cart.list.removeAt(index);
AnimatedListRemovedItemBuilder builder = (context, animation){
return _buildItem(removeItem, animation, index);
};
_key.currentState.removeItem(index, builder);
}
}
您可以复制粘贴运行下面的完整代码
默认 insert/remove 动画持续时间为 Duration(milliseconds: 300)
你可以等 milliseconds: 350
onPressed: () async{
_removeItem(index);
await Future.delayed(Duration(milliseconds: 350), () {});
setState(() {
cart.list.removeAt(index);
});
},
完整代码
import 'package:flutter/material.dart';
class FoodItem {
String name;
String img;
int quantity;
double price;
FoodItem({this.name, this.img, this.quantity, this.price});
}
class CartList {
List<FoodItem> list = [
FoodItem(
name: "1",
img: "https://picsum.photos/250?image=9",
quantity: 1,
price: 10.0),
FoodItem(
name: "2",
img: "https://picsum.photos/250?image=10",
quantity: 2,
price: 20.0),
FoodItem(
name: "3",
img: "https://picsum.photos/250?image=11",
quantity: 3,
price: 30.0),
FoodItem(
name: "4",
img: "https://picsum.photos/250?image=12",
quantity: 4,
price: 40.0)
];
}
class OrderList extends StatefulWidget {
@override
_OrderListState createState() => _OrderListState();
}
class _OrderListState extends State<OrderList> {
CartList cart = CartList();
final GlobalKey<AnimatedListState> _key = GlobalKey();
@override
Widget build(BuildContext context) {
print(cart.list.length);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
elevation: 0.0,
title: Text('Orders'),
centerTitle: true,
),
body: cart.list.length == 0
? Container(child: Text("empty"))
: AnimatedList(
key: _key,
initialItemCount: cart.list.length,
itemBuilder: (context, index, animation) {
print(index);
return _buildItem(cart.list[index], animation, index);
},
),
);
}
Widget _buildItem(FoodItem list, Animation<double> animation, int index) {
return SizeTransition(
sizeFactor: animation,
child: Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('${cart.list[index].img}'),
),
title: Text(cart.list[index].name),
subtitle: Text(
'${cart.list[index].quantity} x ${cart.list[index].price} = ${cart.list[index].quantity * cart.list[index].price}'),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: () async{
_removeItem(index);
await Future.delayed(Duration(milliseconds: 350), () {});
setState(() {
cart.list.removeAt(index);
});
},
),
),
),
);
}
void _removeItem(int index) {
//FoodItem removeItem = cart.list.removeAt(index);
FoodItem removeItem = cart.list[index];
AnimatedListRemovedItemBuilder builder = (context, animation) {
return _buildItem(removeItem, animation, index);
};
_key.currentState.removeItem(index, builder);
//cart.list.removeAt(index);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OrderList(),
);
}
}
我正在做一个项目,我正在其中生成一个订单列表。每当我尝试从列表中删除一个项目。它抛出 RangeError (index): Invalid value: Only valid value is 0: 1
的异常。
但是,它会同时删除该项目。如果存在范围问题,为什么要删除该项目?或者这个错误是什么时候产生的?另一件事是如何在特定小部件中应用 try/catch?
代码如下:
class OrderList extends StatefulWidget {
@override
_OrderListState createState() => _OrderListState();
}
class _OrderListState extends State<OrderList> {
CartList cart = CartList.instance;
final GlobalKey<AnimatedListState> _key = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
elevation: 0.0,
title: Text('Orders'),
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Badge(
child: Icon(Icons.shopping_cart, color: Colors.white, size: 40),
badgeContent: Text(
cart.listLength(),
style: TextStyle(color: Colors.white),
),
badgeColor: Colors.amber,
toAnimate: true,
animationType: BadgeAnimationType.fade,
),
),
],
),
body: AnimatedList(
key: _key,
initialItemCount: cart.list.length,
itemBuilder: (context, index, animation) {
return _buildItem(cart.list[index], animation, index);
},
),
);
}
Widget _buildItem(FoodItem list, Animation<double> animation, int index) {
return SizeTransition(
sizeFactor: animation,
child: Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('assets/${cart.list[index].img}'),
),
title: Text(cart.list[index].name),
subtitle: Text(
'${cart.list[index].quantity} x ${cart.list[index].price} = ${cart.list[index].quantity * cart.list[index].price}'),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: (){
_removeItem(index);
setState(() {
});
},
),
),
),
);
}
void _removeItem(int index) {
FoodItem removeItem = cart.list.removeAt(index);
AnimatedListRemovedItemBuilder builder = (context, animation){
return _buildItem(removeItem, animation, index);
};
_key.currentState.removeItem(index, builder);
}
}
您可以复制粘贴运行下面的完整代码
默认 insert/remove 动画持续时间为 Duration(milliseconds: 300)
你可以等 milliseconds: 350
onPressed: () async{
_removeItem(index);
await Future.delayed(Duration(milliseconds: 350), () {});
setState(() {
cart.list.removeAt(index);
});
},
完整代码
import 'package:flutter/material.dart';
class FoodItem {
String name;
String img;
int quantity;
double price;
FoodItem({this.name, this.img, this.quantity, this.price});
}
class CartList {
List<FoodItem> list = [
FoodItem(
name: "1",
img: "https://picsum.photos/250?image=9",
quantity: 1,
price: 10.0),
FoodItem(
name: "2",
img: "https://picsum.photos/250?image=10",
quantity: 2,
price: 20.0),
FoodItem(
name: "3",
img: "https://picsum.photos/250?image=11",
quantity: 3,
price: 30.0),
FoodItem(
name: "4",
img: "https://picsum.photos/250?image=12",
quantity: 4,
price: 40.0)
];
}
class OrderList extends StatefulWidget {
@override
_OrderListState createState() => _OrderListState();
}
class _OrderListState extends State<OrderList> {
CartList cart = CartList();
final GlobalKey<AnimatedListState> _key = GlobalKey();
@override
Widget build(BuildContext context) {
print(cart.list.length);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
elevation: 0.0,
title: Text('Orders'),
centerTitle: true,
),
body: cart.list.length == 0
? Container(child: Text("empty"))
: AnimatedList(
key: _key,
initialItemCount: cart.list.length,
itemBuilder: (context, index, animation) {
print(index);
return _buildItem(cart.list[index], animation, index);
},
),
);
}
Widget _buildItem(FoodItem list, Animation<double> animation, int index) {
return SizeTransition(
sizeFactor: animation,
child: Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('${cart.list[index].img}'),
),
title: Text(cart.list[index].name),
subtitle: Text(
'${cart.list[index].quantity} x ${cart.list[index].price} = ${cart.list[index].quantity * cart.list[index].price}'),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: () async{
_removeItem(index);
await Future.delayed(Duration(milliseconds: 350), () {});
setState(() {
cart.list.removeAt(index);
});
},
),
),
),
);
}
void _removeItem(int index) {
//FoodItem removeItem = cart.list.removeAt(index);
FoodItem removeItem = cart.list[index];
AnimatedListRemovedItemBuilder builder = (context, animation) {
return _buildItem(removeItem, animation, index);
};
_key.currentState.removeItem(index, builder);
//cart.list.removeAt(index);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OrderList(),
);
}
}