android - 管理另一个类的一个页面的状态
问题描述
我正在构建一个用于培训的应用程序,Flutter
但实际上我被困在了过滤器功能中。
我有一个ListView
从 TheMovieDB API 和一个 ModalBottomSheet 获取数据的地方,其中包含三个 FilterChips 用于选择过滤条件(流行、评分最高和最新电影)。
这就是我卡住的地方。当用户通过“performUpdate()”按下 ModalBottomSheet 中的“完成”按钮时,我想调用“_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 是一个非常强大的框架,它使用 pub/sub 系统允许您的视图订阅模型的更改,同时使用“actions”和“reducers”系统来更新模型。
可以在此处找到有关在 Flutter 中启动和运行 Redux 的精彩教程
或者,您可以查看scoped model,这是 Flutter 的另一个状态管理库。范围模型的能力较差,但对于简单的用例来说可能绰绰有余。
进一步阅读:
推荐阅读
- javascript - 如何将带有数组的 javascript 对象转换为具有相应名称和值的对象数组?
- cobol - 程序运行但出错
- html - 创建 XSLT 产品页面
- c# - 为什么表达式主体方法中不需要 return 关键字
- python - 如果在另一个数据框列 pandas 中找到列中的值,则返回值
- python - 从导航抽屉 KivyMD 创建新屏幕
- python - 您如何使用 json.dumps 格式化 Python,以使您的 Lambda 函数正确响应 API Gateway?
- java - 从昵称获取用户 - Java Discord (JDA)
- amazon-web-services - Athena 存储查询结果的最佳实践
- sql - SQL "to" 关键字——特别是 POSTGRESQL