我的 gridView 与 DB(sqlite) 一起工作,它在添加项目时有很好的动画,但是当用 dismissible 删除时它有丑陋的屏幕更新没有动画。我做了所有删除时仍然无法制作动画。
动画只有在我添加全局键或唯一键时才有效,但当我单击某个地方时它会更新,即使它与它没有任何联系也会更新整个屏幕。在 GrivView 构建器中可关闭:
import 'package:flutter/material.dart';
import 'package:recipe_proj/model/recipe_model.dart';
import 'package:recipe_proj/db/db_helper.dart';
import 'package:recipe_proj/main.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:recipe_proj/animation/m_animation.dart';
class Grid extends StatefulWidget {
const Grid({Key? key}) : super(key: key);
@override
GridState createState() => GridState();
}
class GridState extends State<Grid> {
List<Map<String, dynamic>> myData = [];
bool _isLoading = true;
bool isPressed = false;
Color color = const Color.fromRGBO(248, 249, 243, 1);
final List<bool> pressed = List.generate(500,(index)=> false);
void _refreshData() async {
final data = await DatabaseHelper.getItems();
setState(() {
myData = data;
_isLoading = false;
});
}
@override
void initState() {
super.initState();
_refreshData();
}
/*final TextEditingController _titleController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
final TextEditingController _timeController = TextEditingController();
final List<TextEditingController> stepsController = [];*/
/*
final _portionController = TextEditingController();
final List<String> _ingredients = [];
final List<TextEditingController> _quaController = [];
int portion = 0;
final List<String> _quantity = [];*/
//Uint8List? imageFile;
Future<void> addItem() async {
await DatabaseHelper.createItem(
Recipe(id: 0, title: '', portion: 0, steps: [], quantity: [], ingredients: [], time: 0)
);
_refreshData();
}
void deleteItem(int id) async {
await DatabaseHelper.deleteItem(id);
_refreshData();
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Рецепт удален успешно'), backgroundColor: Colors.deepOrangeAccent));
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white54,
body: SingleChildScrollView(
child: _isLoading
? const Center(
child: CircularProgressIndicator(),
)
: myData.isEmpty
? Padding(
padding: MediaQuery.of(context).padding * 5,
child: const Center(
child: Text("У вас нет записанных рецептов",
style: TextStyle(
fontSize: 16.0,
color: aDarkGreen,
fontWeight: FontWeight.w700))),
)
: Padding(
padding: MediaQuery.of(context).padding * 1.1,
child: Column(
children: [
const Text("Рецепты",
style: TextStyle(
fontSize: 20.0,
color: aDarkGreen,
fontWeight: FontWeight.w700)),
const SizedBox(
height: 20,
),
Row(
children: [
TextButton(
onPressed: () {
setState(() {
isPressed = false;
});
},
child: Container(
height: 30,
width: MediaQuery.of(context).size.width * 0.4,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0),
color: isPressed
? Colors.white
: aDarkGreen),
child: Center(
child: Text(
"Рецепты",
style: TextStyle(
color: isPressed
? aDarkGreen
: color),
)),
),
),
const SizedBox(
width: 5.0,
),
TextButton(
onPressed: () {
setState(() {
isPressed = true;
});
},
child: Container(
height: 30,
width: MediaQuery.of(context).size.width * 0.4,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0),
color: isPressed
? aDarkGreen
: color),
child: Center(
child: Text(
"Коллекции",
style: TextStyle(
color: isPressed
? color
: aDarkGreen),
)),
),
),
],
),
GridView.builder(
scrollDirection: Axis.vertical,
physics: const ScrollPhysics(),
shrinkWrap: true,
itemCount: myData.length,
itemBuilder: (context, index) => AnimationConfiguration.staggeredGrid(
position: index,
columnCount: 2,
duration: const Duration(milliseconds: 1000),
child: ScaleAnimation(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Dismissible(
key: UniqueKey(),
direction: DismissDirection.endToStart,
background: Container(
alignment: Alignment.centerRight,
child: const Padding(
padding: EdgeInsets.only(right: 20.0),
),
),
onDismissed: (direction) {
setState(() {
deleteItem(myData[index]['id']);
});
},
child: Stack(
fit: StackFit.expand,
children: [
Positioned(
left: 0,
right: 0,
child: GestureDetector(
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: SizedBox(
height: 200,
width: 200,
child: myData[index]['image'] == null ?
Image.asset("assets/images/Dish.jpg", fit: BoxFit.cover,
)
: Image.memory(myData[index]['image'], fit: BoxFit.cover,
)
),
),
),
),
Align(
alignment: const Alignment(-1, 0.93),
child: Text(myData[index]['title'], softWrap: true, maxLines: 2, style: const TextStyle(color: Colors.black45, fontFamily: 'Cera Pro', fontSize: 14,
),)
),
Positioned(
top: 170,
left: 10,
child: Row(
children:[
Text(myData[index]['time'], style: const TextStyle(color: Colors.deepOrangeAccent),),
const SizedBox(
width: 2.0,
),
const Text('min', style: TextStyle(color: Colors.deepOrangeAccent)),
],
),
),
Align(
alignment:const Alignment(1.2, 1.17),
child: Container(
height: 46,
width: 46,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30)
),
child: IconButton(
onPressed: (){
setState(() {
for(int i = 0; i< pressed.length; i++){
if(i == index){
pressed[i] =! pressed[i];
}
}
});
},
icon: pressed[index] ? const Icon(Icons.favorite, color: Colors.deepOrangeAccent, size: 22, ) : const Icon(Icons.favorite_outline, color: Colors.deepOrangeAccent, size: 22,),
),
),
),
],
),
),
),
),
),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisExtent: 256,
crossAxisSpacing: 1),
),
],
),
),
),
);
}
}