当我删除和添加项目时,我试图制作一个列表来替换其中的项目并设置动画效果,因此我使用了功能ImplicitlyAnimatedReorderableList<>
,而当我尝试从列表中删除项目时,显示此错误:
════════ Exception caught by widgets library══════════════════════════════
The following RangeError was thrown building AnimatedBuilder(animation: AnimationController#1fbd2(⏮ 0.000; paused)➩_Linear, dirty, state: _AnimatedState#040d2):
RangeError (index): Invalid value: Only valid value is 0: 1
The relevant error-causing widget was:
Reorderable-[<'1'>] file:///C:/Users/bentau/Desktop/checkIt/lib/SlideBar/Pages/ToDo.dart:172:26
When the exception was thrown, this was the stack:
#0 List.[] (dart:core-patch/growable_array.dart:149:60)
#1 _ToDoState.build.<anonymous closure>.<anonymous closure> (package:flutterapp/SlideBar/Pages/ToDo.dart:189:44)
#2 ReorderableState.build.buildChild (package:implicitly_animated_reorderable_list/src/reorderable.dart:123:21)
#3 ReorderableState.build.<anonymous closure> (package:implicitly_animated_reorderable_list/src/reorderable.dart:130:44)
#4 AnimatedBuilder.build (package:flutter/src/widgets/transitions.dart:1012:12)
................................................................................................................
这是我的代码:
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutterapp/SlideBar/Function/SlideBarMain.dart';
import 'package:flutterapp/SlideBar/Function/ToDoClass.dart';
import 'package:implicitly_animated_reorderable_list/implicitly_animated_reorderable_list.dart';
import 'package:implicitly_animated_reorderable_list/transitions.dart';
class ToDo extends StatefulWidget {
@override
_ToDoState createState() => _ToDoState();
}
class _ToDoState extends State<ToDo> {
final GlobalKey<SlideBarMainState> _key = GlobalKey();
final GlobalKey <FormState> formKey = GlobalKey<FormState>();
final GlobalKey<AnimatedListState> listKey = GlobalKey();
List<ToDoData> restory = [ToDoData(Title: null, Context: null, done: false)];
List<ToDoData> Data = [
ToDoData(Title: "Finishing the ToDo", Context: "finish it fast", done: false),
];
int yetdone = 1;
String title;
String TodoContext;
// bool inReorder = false;
//
// ScrollController scrollController;
//
// @override
// void initState() {
// super.initState();
// scrollController = ScrollController();
// }
void onReorderFinished(List<ToDoData> newItems) {
// scrollController.jumpTo(scrollController.offset);
setState(() {
// inReorder = false;
Data
..clear()
..addAll(newItems);
});
}
Widget buildTitle() {
//create title limiting
return TextFormField(
decoration: InputDecoration(labelText: "Title"),
maxLength: 50, //75
// ignore: missing_return
validator: (String value) {
if (value.isEmpty) {
return 'Title is Required';
}
},
onSaved: (String value) {
title = value;
},
);
}
Widget buildTodoContext() {
//create the context
return TextFormField(
decoration: InputDecoration(labelText: "context"),
maxLength: 100,
onSaved: (String value) {
TodoContext = value;
},
);
}
createAddFunction(BuildContext context) {
//new task creator screen
return showDialog(context: context, builder: (context) {
return AlertDialog(
title: Text("Add New ToDo"),
content: Container(
margin: EdgeInsets.all(24),
child: Form(key: formKey, child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildTitle(),
buildTodoContext(),
SizedBox(height: 50,),
RaisedButton(
child: Text("Save"),
onPressed: () {
formKey.currentState.save();
if (!formKey.currentState.validate()) {
return;
}
else {
Data.insert(yetdone, ToDoData(Title: title, Context: TodoContext, done: false,));
setState(() {
yetdone++;
});
Navigator.of(context).pop();
};
},
)
],
)
))
);
});
}
Widget DoneBack() {
//the background when you slide task right
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20.0),
color: Colors.green,
child: const Icon(Icons.done, color: Colors.white,),
);
}
Widget DeleteBack() {
return Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20.0),
color: Colors.red,
child: const Icon(Icons.delete, color: Colors.white,),
);
}
@override
Widget build(BuildContext context) {
return Scaffold( // screen background
backgroundColor: Colors.grey[600],
appBar: AppBar(
backgroundColor: Colors.grey[900],
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () => createAddFunction(context),
),
],
leading:
IconButton(
icon: Icon(Icons.settings),
onPressed: () => _key.currentState.SwitchFunc(),
),
title: Text('ToDo'),
centerTitle: true,
),
body:
Stack( // list of tasks
children: <Widget>[
ImplicitlyAnimatedReorderableList<ToDoData>(
items: Data,
shrinkWrap: true,
areItemsTheSame: (a, b) => a.Index == b.Index,
onReorderFinished: (item, from, to, newItems) => onReorderFinished(newItems),
removeDuration: Duration.zero,
itemBuilder: (context, itemAnimation, item, index) {
return Reorderable(
key: ValueKey(index.toString()),
builder: (context, dragAnimation, inDrag) {
final t = dragAnimation.value;
final elevation = lerpDouble(0, 8, t);
final color = Color.lerp(Colors.white, Colors.white.withOpacity(0.8), t);
return SizeFadeTransition(
sizeFraction: 0.7,
curve: Curves.easeInOut,
animation: itemAnimation,
child: Padding(
padding: EdgeInsets.fromLTRB(35, 5, 35, 5),
child: Dismissible(
key: UniqueKey(),
child: Card(
elevation: elevation,
color: color,
child: Data[index].done ? Stack(
children: <Widget>[
ListTile(
title: RichText(text: TextSpan(
text: Data[index].Title,
style: TextStyle(color: Colors.black,
decoration: TextDecoration.lineThrough)),),
subtitle: RichText(text: TextSpan(
text: Data[index].Context,
style: TextStyle(color: Colors.grey[800],
decoration: TextDecoration.lineThrough)),),
),
Center(
child: SizedBox(height: 80, width: 80, child: Image(image: AssetImage('assets/checkItEmpty.png'),)
),
)
]
) :
ListTile(
title: RichText(text: TextSpan(text: Data[index].Title,
style: TextStyle(color: Colors.black)),),
subtitle: RichText(text: TextSpan(text: Data[index].Context,
style: TextStyle(color: Colors.grey[800])),),
trailing:Handle (
delay: const Duration(milliseconds: 100),
child: Icon(
Icons.list,
color: Colors.grey,
),
)
),
),
onDismissed: (direction) {
setState(() {
restory.add(ToDoData(Title: Data[index].Title, Context: Data[index].Context, Index: index, done: Data[index].done));
Data[index].done ? null : yetdone--;
// listKey.currentState.removeItem(
// index,
// (BuildContext context, Animation<double> animation) => buildItems(scaffold,animation,index),
// duration: Duration.zero,);
});
setState(
() => Data.removeAt(index),
);
if (direction == DismissDirection.startToEnd) {
Data.insert(yetdone, ToDoData(Title: restory.last.Title, Context: restory.last.Context, done: true));
restory.last.Context, done: true));
restory.removeLast();
setState(() {});
}
else {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(
"${restory.last.Title} task has removed"),
action: SnackBarAction(
label: "UNDO",
onPressed: () {
Data.insert(restory.last.Index < yetdone ? restory.last.Index : yetdone, ToDoData(Title: restory.last.Title, Context: restory.last.Context, done: false));
// Data.add( ToDoData(Title: restory.last.Title, Context: restory.last.Context, done: false));
// listKey.currentState.insertItem(restory.last.Index < yetdone ? restory.last.Index : yetdone);
restory.removeLast();
setState(() {
yetdone++;
});
}
),
));
}
},
background: DoneBack(),
secondaryBackground: DeleteBack(),
)
)
);
},
);
},
),
// AnimatedList(
// key: listKey,
// initialItemCount:Data.length,
// itemBuilder: (context,index,animation){
// return buildItems(Scaffold.of(context),animation,index);
// },
// ),
Container(
child: Align(
alignment: Alignment(0, 0.90),
child: RaisedButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
color: Colors.white,
onPressed: () => createAddFunction(context),
child: Text('Add Task',
style: TextStyle(fontSize: 20, color: Colors.black)),
),
),
),
////////////////////////slide bar////////////////
SlideBarMain(
IsHome: false,
key: _key,
),
]
)
);
}