android - 管理来自另一个类的一个页面的状态

标签 android flutter state

我正在构建一个用于在 Flutter 中进行培训的应用程序,但我实际上陷入了过滤器功能。

我有一个 ListView,我从 TheMovieDB API 和一个 ModalBottomSheet 中获取数据,其中包含三个用于选择过滤条件(热门、评分最高和最新电影)的 FilterChips。

这就是我被困的地方。当用户通过“performUpdate()”按下 ModalBottomSheet 中的“Done”按钮时,我想调用“_loadNextPage()”方法,但我不能这样做,因为它们不在同一个类中。

我将在下面发布代码以便更好地理解。

class _HomePageState extends State<HomePage> {
  RequestProvider _requestProvider = new RequestProvider();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FluttieDB"),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.filter_list),
            onPressed: () => buildFilterBottomSheet(),
          )
        ],
      ),
      body: MovieList(_requestProvider, _currentFilter),
    );
  }

  void buildFilterBottomSheet() {
    showModalBottomSheet(
        context: context,
        builder: (builder) {
          return Container(
            height: 150.0,
            decoration: BoxDecoration(color: Colors.white),
            child: Column(
              children: <Widget>[
                buildFilterTitle(context),
                Expanded(
                  child: _FilterChipRow(),
                ),
              ],
            ),
          );
        });
  }

  Widget buildFilterTitle(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0),
      alignment: Alignment.centerLeft,
      height: 46.0,
      decoration: BoxDecoration(color: Colors.blue),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          Text(
            "Filter by",
            style: TextStyle(color: Colors.white, fontSize: 20.0),
          ),
          OutlineButton(
            onPressed: () => performUpdate(context),
            padding: const EdgeInsets.all(0.0),
            shape: const StadiumBorder(),
            child: Text(
              "Done",
              style: TextStyle(color: Colors.white),
            ),
          ),
        ],
      ),
    );
  }

  void performUpdate(BuildContext context) {
    MovieList _movieList = new MovieList(_requestProvider, _currentFilter);
    _movieList.createState()._loadNextPage();
    Navigator.pop(context);
  }
}



class MovieList extends StatefulWidget {
  MovieList(this.provider, this.currentFilter, {Key key}) : super(key: key);

  final RequestProvider provider;
  final String currentFilter;

  @override
  _MovieListState createState() => new _MovieListState();
}

class _MovieListState extends State<MovieList> {
  List<Movie> _movies = List();
  int _pageNumber = 1;
  LoadingState _loadingState = LoadingState.LOADING;
  bool _isLoading = false;

  _loadNextPage() async {
    _isLoading = true;

    try {
      var nextMovies = await widget.provider
          .provideMedia(widget.currentFilter, page: _pageNumber);

      setState(() {
        _loadingState = LoadingState.DONE;
        _movies.addAll(nextMovies);
        _isLoading = false;
        _pageNumber++;
      });
    } catch (e) {
      _isLoading = false;

      if (_loadingState == LoadingState.LOADING) {
        setState(() => _loadingState = LoadingState.ERROR);
      }
    }
  }

  @override
  void initState() {
    super.initState();
    _loadNextPage();
  }

  @override
  Widget build(BuildContext context) {
    switch (_loadingState) {
      case LoadingState.DONE:
        return ListView.builder(
            itemCount: _movies.length,
            itemBuilder: (BuildContext context, int index) {
              if (!_isLoading && index > (_movies.length * 0.7)) {
                _loadNextPage();
              }

              return MovieListItem(_movies[index]);
            });
      case LoadingState.ERROR:
        return Center(
            child: Text("Error retrieving movies, check your connection"));
      case LoadingState.LOADING:
        return Center(child: CircularProgressIndicator());
      default:
        return Container();
    }
  }
}

如您所见,我在 performUpdate() 中做了一些实验,但它不会使用过滤器中的选定选项刷新 ListView,我认为这不是实现我想要的效果的最佳方式。

谢谢,如果这个问题有点愚蠢,我们深表歉意。我是 Flutter 的新手。

最佳答案

Redux是一个很棒的状态管理库,起源于 React 和 JS,但已经移植到 Dart,并且还有一个 flutter 特定的库。 Redux 是一个非常强大的框架,它使用发布/订阅系统允许您的 View 订阅模型的更改,同时使用“ Action ”和“缩减器”系统来更新模型。

在 Flutter 中启动和运行 Redux 的精彩教程 can be found here

或者,您可以查看 scoped model ,这是 Flutter 的另一个状态管理库。作用域模型的能力较差,但对于简单的用例来说可能绰绰有余。

进一步阅读:

关于android - 管理来自另一个类的一个页面的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52377030/

相关文章:

firebase - 在flutter中增加Firebase字段值?

dart - ListView.builder 不工作

javascript - 这不是纯函数吗?

dart - 无法在 onDismissible 中删除

go - 在Lambda中传递Xray上下文

javascript - 在 React 的特定输入字段中输入文本后如何启用按钮?

android - Android Activity 中保存的实例状态未保留的保留 fragment

android - 将 productFlavor 添加到实验性 Android gradle 插件库

java - j2me和ksoap如何获取asp.net webservice中的特定元素

android - File.delete() 不会删除 Android 上的符号链接(symbolic link)?