Flutter 在navigator.pop()之后使用提供程序删除播放列表项

Flutter 在navigator.pop()之后使用提供程序删除播放列表项,flutter,dart,Flutter,Dart,在“我的应用”屏幕上查看播放列表时,您可以选择删除整个播放列表 当前正在查看的屏幕是播放列表详细信息屏幕。它有一个依赖项,就是我试图删除的播放列表本身(无人机和人工智能)。 在删除播放列表之前,我需要完成Nav.pop(),并处理此屏幕的小部件树 按delete键后,它会调用Nav.pop()两次,一次删除弹出模式,一次导航回播放列表页面。在使用removePlaylist()删除当前屏幕上的播放列表之前,我需要完成返回到播放列表屏幕的转换,否则此屏幕的依赖项在其仍在视图中时不存在,因此会出现

在“我的应用”屏幕上查看播放列表时,您可以选择删除整个播放列表

当前正在查看的屏幕是播放列表详细信息屏幕。它有一个依赖项,就是我试图删除的播放列表本身(无人机和人工智能)。 在删除播放列表之前,我需要完成Nav.pop(),并处理此屏幕的小部件树

按delete键后,它会调用Nav.pop()两次,一次删除弹出模式,一次导航回播放列表页面。在使用removePlaylist()删除当前屏幕上的播放列表之前,我需要完成返回到播放列表屏幕的转换,否则此屏幕的依赖项在其仍在视图中时不存在,因此会出现错误。当前,在转换到上一个屏幕的过程中,您可以看到由于项目被删除而引发的错误,但仍然部分显示在屏幕上。该项显然不再存在,这就是抛出错误的原因,但如何避免此错误?我尝试使用Future.delayed然后删除该项,但屏幕已被释放,并且在执行时状态不稳定

错误:错误状态:无元素

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