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

Posted

技术标签:

【中文标题】Flutter:Dismissible 小部件内的 SnackBar 无法正常工作【英文标题】:Flutter: SnackBar inside Dismissible widget is not working properly 【发布时间】:2020-12-18 04:04:31 【问题描述】:

我的主屏幕是一个Scaffold,其主体处有一个Dismissible 小部件列表。每个Dismissible 的孩子都是我创建的自定义小部件,名为Box。我有一个FloatingActionButton,它会将我带到一个新屏幕,我可以在其中将更多Boxes 添加到列表中。 (每个Box 接收一个字符串作为参数,用作其标题)。

我希望方法 onDismissed 显示带有文本“(框的标题)排除”的 SnackBar。但是,这并没有按预期工作。问题是它总是显示最后一个框的标题,而不是我刚刚解散的标题。例如,如果我添加了一个名为“Box 1”的Box,然后添加了一个名为“Box 2”的Box,然后我关闭了“Box 1”,那么小吃店将显示“Box 2 exclude”。

我做错了什么?

以下是相关代码:

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,
      ),
    );
  

这里是 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),
            ),
          )
        ]));
  

【问题讨论】:

【参考方案1】:

我认为问题在于您首先删除了列表中的项目。当您显示 SnackBar 时,该项目已被删除,因此您无法在列表中访问它。所以我建议先显示 Snackbar 然后删除该项目。

像这样:(在你的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]));
    ,

【讨论】:

以上是关于Flutter:Dismissible 小部件内的 SnackBar 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

被解雇的 Dismissible 小部件仍然是颤动树的一部分

在 Flutter 测试中查找 CustomScrollView 内的小部件

如何在 Flutter 中对齐小部件内的按钮

如何在 Flutter 中的行小部件内的容器上添加边框?

当setState Flutter时,PageViewer内的小部件没有改变

Dismissible confirmDismiss 结合新的路由导航导致 Flutter 崩溃