[英]What is the correct way to use Dismissible Widget inside CustomScrollView in flutter?
I am trying to put basic DismissibleWidget inside CustomScrollView.我正在尝试将基本的 DismissibleWidget 放在 CustomScrollView 中。 Here is the code这是代码
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),
),
);
}
}
But when ListTile is tapped and user is routed to SecondPage;但是当点击 ListTile 并且用户被路由到 SecondPage 时; and user navigates back it shows following errors.并且用户导航回它显示以下错误。
A dismissed Dismissible widget is still part of the tree.关闭的 Dismissible 小部件仍然是树的一部分。 Make sure to immediately remove the Dismissible widget from the application once that handler has fired.确保在该处理程序触发后立即从应用程序中删除 Dismissible 小部件。
Normally this would be solved by using ListView.builder when not using Slivers as follow.通常,当不使用 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);
});
},
))
But I cannot find way to get rid of this error while using CustomScrollView.但是我在使用 CustomScrollView 时找不到消除这个错误的方法。
You need to use removeAt
inside setState
您需要在setState
使用removeAt
You can copy paste run full code below您可以在下面复制粘贴运行完整代码
code snippet代码片段
onDismissed: (dismissDirection) {
setState(() {
someList.removeAt(index);
});
}
working demo工作演示
full code完整代码
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.