繁体   English   中英

在颤动中的 CustomScrollView 中使用 Dismissible Widget 的正确方法是什么?

[英]What is the correct way to use Dismissible Widget inside CustomScrollView in flutter?

我正在尝试将基本的 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 时找不到消除这个错误的方法。

您需要在setState使用removeAt
您可以在下面复制粘贴运行完整代码
代码片段

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

暂无
暂无

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

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