Flutter 在navigator.pop()之后使用提供程序删除播放列表项
在“我的应用”屏幕上查看播放列表时,您可以选择删除整个播放列表 当前正在查看的屏幕是播放列表详细信息屏幕。它有一个依赖项,就是我试图删除的播放列表本身(无人机和人工智能)。 在删除播放列表之前,我需要完成Nav.pop(),并处理此屏幕的小部件树 按delete键后,它会调用Nav.pop()两次,一次删除弹出模式,一次导航回播放列表页面。在使用removePlaylist()删除当前屏幕上的播放列表之前,我需要完成返回到播放列表屏幕的转换,否则此屏幕的依赖项在其仍在视图中时不存在,因此会出现错误。当前,在转换到上一个屏幕的过程中,您可以看到由于项目被删除而引发的错误,但仍然部分显示在屏幕上。该项显然不再存在,这就是抛出错误的原因,但如何避免此错误?我尝试使用Future.delayed然后删除该项,但屏幕已被释放,并且在执行时状态不稳定 错误:错误状态:无元素 removePlaylist():Flutter 在navigator.pop()之后使用提供程序删除播放列表项,flutter,dart,Flutter,Dart,在“我的应用”屏幕上查看播放列表时,您可以选择删除整个播放列表 当前正在查看的屏幕是播放列表详细信息屏幕。它有一个依赖项,就是我试图删除的播放列表本身(无人机和人工智能)。 在删除播放列表之前,我需要完成Nav.pop(),并处理此屏幕的小部件树 按delete键后,它会调用Nav.pop()两次,一次删除弹出模式,一次导航回播放列表页面。在使用removePlaylist()删除当前屏幕上的播放列表之前,我需要完成返回到播放列表屏幕的转换,否则此屏幕的依赖项在其仍在视图中时不存在,因此会出现
class playlisLocal与ChangeNotifier{
var singleton=singleton();
列表_项=[];
列出获取项目{
返回[…_项];
}
作废删除播放列表(播放列表项){
列出新项=[…_项];
newItems.removehere((Playlist Playlist)=>item.title==Playlist.title);
保存播放列表(新项目);
_项目=新项目;
notifyListeners();
}
}
底部模态类别:
class BuildModalBottomPlaylistEdit extends StatelessWidget {
final Playlist playlist;
BuildModalBottomPlaylistEdit(this.playlist);
@override
Widget build(BuildContext context) {
return Container(
height: Singleton.instance.screenSize.height * .21,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 8, 10),
child: Text(
playlist.title ,
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
),
),
ListTile(
leading: Icon(
Icons.edit,
color: Colors.black87,
),
title: Text('Edit playlist'),
),
ListTile(
leading: Icon(
Icons.delete,
color: Colors.black87,
),
title: Text('Delete playlist'),
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
Provider.of<PlaylistsLocal>(context, listen: false)
.removePlaylist(playlist);
},
),
],
),
);
}
}
class BuildModalButtomPlayEdit扩展了无状态小部件{
最终播放列表;
BuildModalBottomPlayEdit(this.playlist);
@凌驾
小部件构建(构建上下文){
返回容器(
高度:Singleton.instance.screenSize.height*.21,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
填充物(
填充:从LTRB(15,10,8,10)开始的常数边集,
子:文本(
playlist.title,
样式:TextStyle(fontWeight:fontWeight.w600,fontSize:16),
),
),
列表砖(
领先:图标(
图标。编辑,
颜色:颜色。黑色87,
),
标题:文本(“编辑播放列表”),
),
列表砖(
领先:图标(
图标。删除,
颜色:颜色。黑色87,
),
标题:文本(“删除播放列表”),
onTap:(){
Navigator.of(context.pop();
Navigator.of(context.pop();
Provider.of(上下文,侦听:false)
.删除播放列表(播放列表);
},
),
],
),
);
}
}
使用当前代码,将导航到播放列表屏幕,然后删除播放列表。这是导致错误的原因。可能的解决方案是在执行第一次导航(删除弹出模式)后,删除播放列表,然后导航回播放列表屏幕。
移动
Provider.of(上下文,listen:false)。移除播放列表(playlist)代码>位于(context.pop()的两个Navigator.of之间代码>
请参阅此代码段:
class BuildModalBottomPlaylistEdit extends StatelessWidget {
final Playlist playlist;
BuildModalBottomPlaylistEdit(this.playlist);
@override
Widget build(BuildContext context) {
return Container(
height: Singleton.instance.screenSize.height * .21,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 8, 10),
child: Text(
playlist.title ,
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
),
),
ListTile(
leading: Icon(
Icons.edit,
color: Colors.black87,
),
title: Text('Edit playlist'),
),
ListTile(
leading: Icon(
Icons.delete,
color: Colors.black87,
),
title: Text('Delete playlist'),
onTap: () {
Navigator.of(context).pop();
Provider.of<PlaylistsLocal>(context, listen: false)
.removePlaylist(playlist);
Navigator.of(context).pop();
},
),
],
),
);
}
}
class BuildModalButtomPlayEdit扩展了无状态小部件{
最终播放列表;
BuildModalBottomPlayEdit(this.playlist);
@凌驾
小部件构建(构建上下文){
返回容器(
高度:Singleton.instance.screenSize.height*.21,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
填充物(
填充:从LTRB(15,10,8,10)开始的常数边集,
子:文本(
playlist.title,
样式:TextStyle(fontWeight:fontWeight.w600,fontSize:16),
),
),
列表砖(
领先:图标(
图标。编辑,
颜色:颜色。黑色87,
),
标题:文本(“编辑播放列表”),
),
列表砖(
领先:图标(
图标。删除,
颜色:颜色。黑色87,
),
标题:文本(“删除播放列表”),
onTap:(){
Navigator.of(context.pop();
Provider.of(上下文,侦听:false)
.删除播放列表(播放列表);
Navigator.of(context.pop();
},
),
],
),
);
}
}
试试这个代码片段
class BuildModalBottomPlaylistEdit extends StatelessWidget {
final Playlist playlist;
BuildModalBottomPlaylistEdit(this.playlist);
@override
Widget build(BuildContext context) {
return Container(
height: Singleton.instance.screenSize.height * .21,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 8, 10),
child: Text(
playlist.title ,
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
),
),
ListTile(
leading: Icon(
Icons.edit,
color: Colors.black87,
),
title: Text('Edit playlist'),
),
ListTile(
leading: Icon(
Icons.delete,
color: Colors.black87,
),
title: Text('Delete playlist'),
onTap: ()aysnc{
Navigator.of(context).pop();
await Provider.of<PlaylistsLocal>(context, listen: false)
.removePlaylist(playlist);
Navigator.of(context).pop();
},
),
],
),
);
}
}
class BuildModalButtomPlayEdit扩展了无状态小部件{
最终播放列表;
BuildModalBottomPlayEdit(this.playlist);
@凌驾
小部件构建(构建上下文){
返回容器(
高度:Singleton.instance.screenSize.height*.21,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
填充物(
填充:从LTRB(15,10,8,10)开始的常数边集,
子:文本(
playlist.title,
样式:TextStyle(fontWeight:fontWeight.w600,fontSize:16),
),
),
列表砖(
领先:图标(
图标。编辑,
颜色:颜色。黑色87,
),
标题:文本(“编辑播放列表”),
),
列表砖(
领先:图标(
图标。删除,
颜色:颜色。黑色87,
),
标题:文本(“删除播放列表”),
onTap:()aysnc{
Navigator.of(context.pop();
wait Provider.of(上下文,侦听:false)
.删除播放列表(播放列表);
class BuildModalBottomPlaylistEdit extends StatelessWidget {
final Playlist playlist;
BuildModalBottomPlaylistEdit(this.playlist);
@override
Widget build(BuildContext context) {
return Container(
height: Singleton.instance.screenSize.height * .21,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 8, 10),
child: Text(
playlist.title ,
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
),
),
ListTile(
leading: Icon(
Icons.edit,
color: Colors.black87,
),
title: Text('Edit playlist'),
),
ListTile(
leading: Icon(
Icons.delete,
color: Colors.black87,
),
title: Text('Delete playlist'),
onTap: ()aysnc{
Navigator.of(context).pop();
await Provider.of<PlaylistsLocal>(context, listen: false)
.removePlaylist(playlist);
Navigator.of(context).pop();
},
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<PlaylistsLocal>(
create: (context) => PlaylistsLocal(),
child: MaterialApp(
home: HomePage(),
)
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Playlists', style: TextStyle(fontSize: 30),),
Expanded(
flex: 8,
child: ListView.builder(
itemCount: Provider.of<PlaylistsLocal>(context).items.length,
itemBuilder: (context, i) {
Playlist playlist = Provider.of<PlaylistsLocal>(context).items[i];
return Container(
color: Colors.yellow,
child: ListTile(
title: InkWell(
child: Text(playlist.title),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (context) => PlaylistDetailPage(playlist))
),
),
),
);
}
)
),
],
),
),
);
}
}
/// Playlist detail page uses Playlist object for title data
class PlaylistDetailPage extends StatelessWidget {
final Playlist playlist;
PlaylistDetailPage(this.playlist);
@override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
child: Container(
color: Colors.yellow,
child: Center(
child: Text('${playlist.title} DETAILS Page\n (click anywhere)'),
),
),
onTap: () => showDialog(
context: context,
barrierDismissible: true,
builder: (context) => BottomModalPlaylistEdit(playlist),
),
),
);
}
}
class BottomModalPlaylistEdit extends StatelessWidget {
final Playlist playlist;
BottomModalPlaylistEdit(this.playlist);
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(playlist.title),
content: Text('Playlist details are here'),
actions: [
RaisedButton(child: Text('Back'), onPressed: Navigator.of(context).pop),
RaisedButton(child: Text('Delete'),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
Provider.of<PlaylistsLocal>(context, listen: false)
.removePlaylist(playlist);
},
)
]
);
}
}
class Playlist {
String title;
Playlist(this.title);
}
class Singleton {}
class PlaylistsLocal with ChangeNotifier {
var singleton = Singleton();
List<Playlist> _items = [Playlist('Hairband Hits')];
List<Playlist> get items {
return [..._items];
}
void removePlaylist(Playlist item) {
List<Playlist> newItems = [..._items];
newItems.removeWhere((Playlist playlist) => item.title == playlist.title);
savePlaylist(newItems);
_items = newItems;
notifyListeners();
}
void savePlaylist(List<Playlist> items) {
// Not sure what you do here
}
void resetPlaylist() {
_items = [Playlist('Hairband Hits')];
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Playlists', style: TextStyle(fontSize: 30),),
Expanded(
flex: 8,
child: Consumer<PlaylistsLocal>(
builder: (context, value, child) => ListView.builder(
itemCount: Provider.of<PlaylistsLocal>(context).items.length,
itemBuilder: (context, i) {
Playlist playlist = Provider.of<PlaylistsLocal>(context).items[i];
return Container(
color: Colors.yellow,
child: ListTile(
title: InkWell(
child: Text(playlist.title),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (context) => PlaylistDetailPage(playlist))
),
),
),
);
}
)
)
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RaisedButton(
child: Text('Reset'),
onPressed: Provider.of<PlaylistsLocal>(context).resetPlaylist,
)
],
)
],
),
),
);
}
}