Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 颤振提供者/使用者UI未随数据更改而更新_Flutter_Dart - Fatal编程技术网

Flutter 颤振提供者/使用者UI未随数据更改而更新

Flutter 颤振提供者/使用者UI未随数据更改而更新,flutter,dart,Flutter,Dart,我是一个新手,正在开发我的第一个应用程序。根据数据更改更新UI时遇到问题。我遵循了本教程:(并添加了额外的特性),该教程使用GetIt库遍历MVVM设置 我已成功地通过viewmodels和services传递了数据,但无法更新UI。本质上,我希望用户能够点击他们观察列表上的电影并将其删除。这在数据意义上是有效的,但当我返回时,我的监视列表UI并没有更新。我的整个项目可在上获得,但此问题的核心文件如下所示: 定位镖 监视列表\u服务.dart 。。。 ... 类WatchlistService{

我是一个新手,正在开发我的第一个应用程序。根据数据更改更新UI时遇到问题。我遵循了本教程:(并添加了额外的特性),该教程使用GetIt库遍历MVVM设置

我已成功地通过viewmodels和services传递了数据,但无法更新UI。本质上,我希望用户能够点击他们观察列表上的电影并将其删除。这在数据意义上是有效的,但当我返回时,我的监视列表UI并没有更新。我的整个项目可在上获得,但此问题的核心文件如下所示:

定位镖

监视列表\u服务.dart

。。。
...
类WatchlistService{
Api_Api=定位器();
列表_watchlist=[];
List get watchlist=>\u watchlist;
未来getUserWatchlist(用户)异步{
for(user.watchlistId中的字符串id){
_add(wait_api.getMovie(id));
}
}
布尔因利斯特(电影){
return_watchlist.contains(电影);
}
作废编辑列表(电影、bool-remove){
如果(删除){
_监视列表。删除(电影);
打印(“从监视列表服务中的列表中删除”+movie.title+”);
}否则{
_添加(电影);
打印(“将“+movie.title+”添加到观察列表服务的列表中”);
}
}
}
监视列表\u型号dart

。。。
...
类WatchlistModel扩展了BaseModel{
WatchlistService_WatchlistService=locator();
List get watchlist=>\u watchlistService.watchlist;
未来getWatchlist(用户)异步{
设置状态(ViewState.Busy);
wait_watchlistService.getUserWatchlist(用户);
设置状态(ViewState.Idle);
}
}
监视列表\u view.dart

。。。
...
类WatchlistView扩展了无状态小部件{
小部件_createMovieCard(电影、构建上下文){
返回CupertinoButton(
按下:()=>\u获取信息(电影、上下文),
孩子:图像.网络(电影.海报(185)),
);
}
_getInfo(电影、构建上下文){
Navigator.pushNamed(
上下文
“详情”,
论点:电影,
);
}
@凌驾
小部件构建(构建上下文){
返回基本视图(
onModelReady:(model)=>model.getWatchlist(Provider.of(context)),
生成器:(上下文、模型、子项)=>Scaffold(
正文:model.state==ViewState.Idle
?自定义滚动视图(
主要:错误,
条子:[
CupertinoSliverNavigationBar(
largeTitle:Text(“我的观察列表”),
尾随:材料(
颜色:颜色。透明,
孩子:我的钮扣(
图标:图标(CupertinoIcons.添加圆形实体),
按下:()=>
Navigator.pushNamed(上下文“搜索”),
),
银栅(
gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(
交叉轴计数:2,
儿童方面:
MediaQuery.of(context).size.width/
(MediaQuery.of(context.size.height/1.7)),
代表:SliverChildBuilderDelegate(
(BuildContext上下文,int索引){
返回_createMovieCard(
监视列表[索引],上下文);
},childCount:model.watchlist.length),
),
],
)
:居中(子项:CircularProgressIndicator());
}
}
删除btn_model.dart

。。。
...
类RemoveButtonModel扩展了BaseModel{
WatchlistService_WatchlistService=locator();
//bool watchlistStatus()
无效移除电影(电影){
打印(“从移除按钮模型中的列表中移除“+movie.title+”);
_editList(电影,真);
notifyListeners();
}
void addMovie(电影){
打印(“将“+movie.title+”添加到移除按钮模型中的列表中”);
_editList(电影,false);
notifyListeners();
}
}
详细信息\u view.dart

。。。
...
类DetailsView扩展了无状态小部件{
_makeStars(双平均值){
双精度=voteAverage/2;
印刷(真实化);
回报率(
颜色:颜色。黄色调[700],
价值:真实,
尺寸:GFSize.SMALL,
Allowalflating:是的,
);
}
_背景(字符串链接){
如果(链接!=null){
返回Image.network(“http://image.tmdb.org/t/p/w780/$link”);
}否则
返回Image.asset(“assets/images/transparent.png”);
}
@凌驾
小部件构建(构建上下文){
Movie Movie=ModalRoute.of(context).settings.arguments;
返回脚手架(
正文:自定义滚动视图(
条子:[
CupertinoSliverNavigationBar(
largeTitle:文本(电影名称),
尾随:
材质(颜色:Colors.transparent,子级:RemoveButton(电影)),
),
滑动双轴适配器(
子:列(
儿童:[
填充(填充:仅限边集(顶部:20)),
中心(儿童:Image.network(movie.getPoster(342)),
居中(
子:容器(
填充:边缘设置。全部(10),
儿童:中心(
孩子:文本(movie.title,
textAlign:textAlign.center,
样式:TextStyle(
fontSize:40,fontWeight:fontWeight.w800)),
)),
容器(
填充:仅限边缘设置(底部:10),
孩子:排(
mainAxisAlignment:mainAxisAlignment.space,
...
...
GetIt locator = GetIt.instance;

void setupLocator() {
  locator.registerLazySingleton(() => AuthenticationService());
  locator.registerLazySingleton(() => WatchlistService());
  locator.registerLazySingleton(() => Api());

  locator.registerLazySingleton(() => LoginModel());
  locator.registerFactory(() => HomeModel());
  locator.registerFactory(() => RemoveButtonModel());
  locator.registerFactory(() => WatchlistModel());
}

...
...
class WatchlistService {
  Api _api = locator<Api>();

  List<Movie> _watchlist = [];
  List<Movie> get watchlist => _watchlist;

  Future getUserWatchlist(User user) async {
    for (String id in user.watchlistId) {
      _watchlist.add(await _api.getMovie(id));
    }
  }

  bool inList(Movie movie) {
    return _watchlist.contains(movie);
  }

  void editList(Movie movie, bool remove) {
    if (remove) {
      _watchlist.remove(movie);
      print("removed " + movie.title + " from list in watchlist service");
    } else {
      _watchlist.add(movie);
      print("added " + movie.title + " to list in watchlist service");
    }
  }
}
...
...
class WatchlistModel extends BaseModel {
  WatchlistService _watchlistService = locator<WatchlistService>();

  List<Movie> get watchlist => _watchlistService.watchlist;

  Future getWatchlist(User user) async {
    setState(ViewState.Busy);
    await _watchlistService.getUserWatchlist(user);
    setState(ViewState.Idle);
  }
}

...
...
class WatchlistView extends StatelessWidget {
  Widget _createMovieCard(Movie movie, BuildContext context) {
    return CupertinoButton(
      onPressed: () => _getInfo(movie, context),
      child: Image.network(movie.getPoster(185)),
    );
  }

  _getInfo(Movie movie, BuildContext context) {
    Navigator.pushNamed(
      context,
      "details",
      arguments: movie,
    );
  }

  @override
  Widget build(BuildContext context) {
    return BaseView<WatchlistModel>(
        onModelReady: (model) => model.getWatchlist(Provider.of<User>(context)),
        builder: (context, model, child) => Scaffold(
            body: model.state == ViewState.Idle
                ? CustomScrollView(
                    primary: false,
                    slivers: <Widget>[
                      CupertinoSliverNavigationBar(
                        largeTitle: Text("My Watchlist"),
                        trailing: Material(
                            color: Colors.transparent,
                            child: IconButton(
                                icon: Icon(CupertinoIcons.add_circled_solid),
                                onPressed: () =>
                                    Navigator.pushNamed(context, 'search'))),
                      ),
                      SliverGrid(
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            childAspectRatio:
                                MediaQuery.of(context).size.width /
                                    (MediaQuery.of(context).size.height / 1.7)),
                        delegate: SliverChildBuilderDelegate(
                            (BuildContext context, int index) {
                          return _createMovieCard(
                              model.watchlist[index], context);
                        }, childCount: model.watchlist.length),
                      ),
                    ],
                  )
                : Center(child: CircularProgressIndicator())));
  }
}
...
...

class RemoveButtonModel extends BaseModel {
  WatchlistService _watchlistService = locator<WatchlistService>();

  //bool watchlistStatus()

  void removeMovie(Movie movie) {
    print("removed " + movie.title + " from list in remove button model");
    _watchlistService.editList(movie, true);
    notifyListeners();
  }

  void addMovie(Movie movie) {
    print("added " + movie.title + " to list in remove button model");
    _watchlistService.editList(movie, false);
    notifyListeners();
  }
}
...
...
class DetailsView extends StatelessWidget {
  _makeStars(double voteAverage) {
    double trueRating = voteAverage / 2;
    print(trueRating);
    return GFRating(
      color: Colors.yellowAccent[700],
      value: trueRating,
      size: GFSize.SMALL,
      allowHalfRating: true,
    );
  }

  _backdrop(String link) {
    if (link != null) {
      return Image.network("http://image.tmdb.org/t/p/w780/$link");
    } else
      return Image.asset("assets/images/transparent.png");
  }

  @override
  Widget build(BuildContext context) {
    Movie movie = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          CupertinoSliverNavigationBar(
            largeTitle: Text(movie.title),
            trailing:
                Material(color: Colors.transparent, child: RemoveButton(movie)),
          ),
          SliverToBoxAdapter(
              child: Column(
            children: <Widget>[
              Padding(padding: EdgeInsets.only(top: 20)),
              Center(child: Image.network(movie.getPoster(342))),
              Center(
                  child: Container(
                padding: EdgeInsets.all(10),
                child: Center(
                    child: Text(movie.title,
                        textAlign: TextAlign.center,
                        style: TextStyle(
                            fontSize: 40, fontWeight: FontWeight.w800))),
              )),
              Container(
                padding: EdgeInsets.only(bottom: 10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    _makeStars(movie.voteAverage),
                    Text("platform",
                        style: Theme.of(context).textTheme.headline5),
                  ],
                ),
              ),
              Container(
                padding: EdgeInsets.fromLTRB(20, 0, 10, 50),
                child: Text(movie.overview),
              ),
              _backdrop(movie.backdropPath)
            ],
          ))
        ],
      ),
    );
  }
}
...
...
class RemoveButton extends StatelessWidget {
  final Movie movie;
  RemoveButton(this.movie);

  _showDialog(String id, bool inWatchlist, BuildContext context,
      RemoveButtonModel model) {
    if (inWatchlist) {
      showDialog(
          context: context,
          child: CupertinoAlertDialog(
              title: Text("Remove from your watchlist?"),
              actions: <Widget>[
                CupertinoDialogAction(
                  isDefaultAction: true,
                  onPressed: () =>
                      Navigator.of(context, rootNavigator: true).pop(),
                  child: Text("Cancel"),
                ),
                CupertinoDialogAction(
                  textStyle: TextStyle(color: Colors.red),
                  onPressed: () => _deletelist(id, context, model),
                  child: Text("Remove"),
                )
              ]));
    } else {
      showDialog(
          context: context,
          child: CupertinoAlertDialog(
              title: Text("Add to your watchlist?"),
              actions: <Widget>[
                CupertinoDialogAction(
                  onPressed: () =>
                      Navigator.of(context, rootNavigator: true).pop(),
                  child: Text("Cancel"),
                ),
                CupertinoDialogAction(
                  isDefaultAction: true,
                  onPressed: () => _addList(id, context, model),
                  child: Text("Add"),
                )
              ]));
    }
  }

  _deletelist(String id, BuildContext context, RemoveButtonModel model) {
    model.removeMovie(movie);
    Provider.of<User>(context).deleteFromWatchlist(id);
    //Navigator.pushNamed(context, 'watchlist');
    Navigator.popUntil(context, ModalRoute.withName('watchlist'));
  }

  _addList(String id, BuildContext context, RemoveButtonModel model) {
    model.addMovie(movie);
    Provider.of<User>(context).addToWatchList(id);
    Navigator.popUntil(context, ModalRoute.withName('watchlist'));
  }

  Widget _rightBtn(Movie movie, BuildContext context, RemoveButtonModel model) {
    if (Provider.of<User>(context).inWatchlist(movie)) {
      return IconButton(
          icon: Icon(Icons.remove_circle),
          color: Colors.blue,
          onPressed: () =>
              _showDialog(movie.id.toString(), true, context, model));
    } else {
      return IconButton(
          icon: Icon(Icons.add_circle),
          color: Colors.blue,
          onPressed: () =>
              _showDialog(movie.id.toString(), false, context, model));
    }
  }

  @override
  Widget build(BuildContext context) {
    return BaseView<RemoveButtonModel>(
      builder: (context, model, child) => _rightBtn(movie, context, model),
    );
  }
}