【问题标题】:What is the correct way to use Dismissible Widget inside CustomScrollView in flutter?在 Flutter 中使用 CustomScrollView 中的 Dismissible Widget 的正确方法是什么?
【发布时间】:2019-12-09 04:35:51
【问题描述】:

我正在尝试将基本 DismissibleWidget 放在 CustomScrollView 中。这是代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool change = false;
  List<String> someList;

  @override
  void initState() {
    super.initState();
    someList = List.generate((20), (index) => 'Data $index');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(
          body: CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                title: Text("Dismissible in Slivers"),
              ),
              SliverList(
                delegate: SliverChildBuilderDelegate(
                    (context, index) => Dismissible(
                          key: ValueKey<String>(someList[index]),
                          child: ListTile(
                            title: Text(someList[index]),
                            onTap: () {
                              Navigator.of(context).push(MaterialPageRoute(
                                  builder: (context) =>
                                      SecondPage(someList[index])));
                            },
                          ),
                          onDismissed: (dismissDirection) {
                            someList.remove(index);
                          },
                        ),
                    childCount: someList.length),
              )
            ],
          ),
        ));
  }
}

class SecondPage extends StatelessWidget {
  final String title;

  SecondPage(this.title);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(this.title),
      ),
    );
  }
}

但是当 ListTile 被点击并且用户被路由到 SecondPage 时;并且用户导航回来它显示以下错误。

已关闭的 Dismissible 小部件仍然是树的一部分。确保在触发处理程序后立即从应用程序中删除 Dismissible 小部件。

在不使用 Slivers 时,通常可以使用 ListView.builder 解决,如下所示。

ListView.builder(
itemCount: someList.length,
itemBuilder: (context, index) => Dismissible(
  key: ValueKey<String>(someList[index]),
  child: ListTile(
    title: Text(someList[index]),
    onTap: () {
      Navigator.of(context).push(MaterialPageRoute(
          builder: (context) =>
              SecondPage(someList[index])));
    },
  ),
  onDismissed: (dissmissDirection) {
    setState(() {
      someList.removeAt(index);
    });
  },
))

但我在使用 CustomScrollView 时找不到解决此错误的方法。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您需要在setState 中使用removeAt
    您可以在下面复制粘贴运行完整代码
    代码sn-p

     onDismissed: (dismissDirection) {
                            setState(() {
                              someList.removeAt(index);
                            });
    
                          }
    

    工作演示

    完整代码

        import 'package:flutter/cupertino.dart';
        import 'package:flutter/material.dart';
    
        void main() => runApp(MyApp());
    
        class MyApp extends StatefulWidget {
          @override
          _MyAppState createState() => _MyAppState();
        }
    
        class _MyAppState extends State<MyApp> {
          bool change = false;
          List<String> someList;
    
          @override
          void initState() {
            super.initState();
            someList = List.generate((20), (index) => 'Data $index');
          }
    
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
                title: 'Flutter Demo',
                theme: ThemeData(
                  primarySwatch: Colors.blue,
                ),
                home: Scaffold(
                  body: CustomScrollView(
                    slivers: <Widget>[
                      SliverAppBar(
                        title: Text("Dismissible in Slivers"),
                      ),
                      SliverList(
                        delegate: SliverChildBuilderDelegate(
                                (context, index) => Dismissible(
                              key: ValueKey<String>(someList[index]),
                              child: ListTile(
                                title: Text(someList[index]),
                                onTap: () {
                                  Navigator.of(context).push(MaterialPageRoute(
                                      builder: (context) =>
                                          SecondPage(someList[index])));
                                },
                              ),
                              onDismissed: (dismissDirection) {
                                setState(() {
                                  someList.removeAt(index);
                                });
    
                              },
                            ),
                            childCount: someList.length),
                      )
                    ],
                  ),
                ));
          }
        }
    
        class SecondPage extends StatelessWidget {
          final String title;
    
          SecondPage(this.title);
    
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              body: Center(
                child: Text(this.title),
              ),
            );
          }
        }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 2015-12-22
    • 2018-12-20
    相关资源
    最近更新 更多