简体   繁体   English

Flutter:Dismissible 小部件内的 SnackBar 无法正常工作

[英]Flutter: SnackBar inside Dismissible widget is not working properly

My Home Screen is a Scaffold with a list of Dismissible widgets at its body. My Home Screen 是一个Scaffold ,在其主体上有一个Dismissible小部件列表。 The child of each Dismissible is a custom widget I created, named Box .每个Dismissible的子项都是我创建的自定义小部件,名为Box I have a FloatingActionButton that takes me to a new screen where I can add more Box es to the list.我有一个FloatingActionButton ,它将我带到一个新屏幕,我可以在其中将更多Box es 添加到列表中。 (Each Box receive a String as an argument, that is used as its title). (每个Box接收一个字符串作为参数,用作其标题)。

I want the method onDismissed to show a SnackBar with the text "(Title of the box) excluded".我希望onDismissed方法显示带有文本“(框的标题)已排除”的SnackBar However, this is not working as expected.但是,这没有按预期工作。 The problem is that it always displays the title of the last box included, and not the title of the one I just dismissed.问题是它总是显示包含的最后一个框的标题,而不是我刚刚忽略的那个框的标题。 For example, if I add a Box named "Box 1", and then a Box named "Box 2", and then I dismiss the "Box 1", the snackbar will say "Box 2 excluded".例如,如果我添加一个名为“ Box 1”的Box ,然后添加一个名为“Box 2”的 Box,然后关闭“Box 1”,小吃店将显示“排除 Box 2”。

What am I doing wrong?我究竟做错了什么?

Here is the relevant code:这是相关代码:

import 'package:flutter/material.dart';
import 'box.dart';
import 'addCounter.dart';

class Home extends StatefulWidget {
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {

  List<String> lista;

  void incrementLista(String novoItem) {
    print('$lista');
    setState(() {
      lista.add(novoItem);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counters'),
        backgroundColor: Colors.black,
      ),
      body: ListView.builder(
        itemCount: lista.length,
        itemBuilder: (context, index) {
          return Dismissible(
              background: Container(color: Colors.grey[800], child: Icon(Icons.delete, color: Colors.grey[100])),
              key: Key(lista[index]),
              onDismissed: (direction) {
                setState(() {
                  lista.removeAt(index);
                });
                Scaffold.of(context).showSnackBar(
                    SnackBar(content: Text(lista[index] + ' excluded.')));
              },
              child: Box(lista[index]));
        },
      ),
      floatingActionButton: FloatingActionButton(
          backgroundColor: Colors.grey[1000],
          onPressed: () {
            //Navega para tela de adicionar tarefa
            Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (context) => AddCounter(f: incrementLista)));
          },
          child: Icon(Icons.add, color: Colors.white)),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomNavigationBar(
        //backgroundColor: Colors.grey[50],
        unselectedItemColor: Colors.grey[700],
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.list),
            title: Text('List'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.insert_chart),
            title: Text('Chart'),
          ),
        ],
        // currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue,
        //onTap: _onItemTapped,
      ),
    );
  }
}

And here is the code of the addCounter.dart:这是 addCounter.dart 的代码:

import 'package:flutter/material.dart';

class AddCounter extends StatefulWidget {
  final Function f;
  AddCounter({@required this.f});

  @override
  _AddCounterState createState() => _AddCounterState();
}

class _AddCounterState extends State<AddCounter> {
  final myController = TextEditingController();

  @override
  void dispose() {
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Add a counter'),
          backgroundColor: Colors.blue,
        ),
        body: Column(children: [
          Padding(
            padding: EdgeInsets.all(15),
            child: TextField(
              controller: myController,
              decoration: InputDecoration(
                  enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.blue, width: 2)),
                  hintText: 'Type a name for the counter'),
            ),
          ),
          RaisedButton(
            color: Colors.green,
            onPressed: () {
              widget.f(myController.text);
              Navigator.pop(context);
            },
            child: Text(
              'Save',
              style: TextStyle(color: Colors.white),
            ),
          )
        ]));
  }
}

I think the problem is that you first remove the item of the list.我认为问题在于您首先删除了列表中的项目。 When you show the SnackBar the item is already removed so you can't access it in the list.当您显示 SnackBar 时,该项目已被删除,因此您无法在列表中访问它。 So I would suggest to first show the Snackbar and then remove the item.所以我建议先显示 Snackbar 然后删除该项目。

Like this: (In your itemBuilder )像这样:(在你的itemBuilder

return Dismissible(
          background: Container(color: Colors.grey[800], child: Icon(Icons.delete, 
                          color: Colors.grey[100])),
          key: Key(lista[index]),
          onDismissed: (direction) {
            Scaffold.of(context).showSnackBar(
                SnackBar(content: Text(lista[index] + ' excluded.')));

            setState(() {
              lista.removeAt(index);
            });
          },
          child: Box(lista[index]));
    },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM