GridView 中的 Flutter dismissible 动画

问题描述 投票:0回答:0

我的 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),
                        ),
                      ],
                    ),
                  ),
      ),
    );
  }
}
flutter animation gridview
© www.soinside.com 2019 - 2024. All rights reserved.