我正在尝试在我的 Flutter 应用程序中实现 UI 和逻辑之间的完全分离,甚至是永恒状态。
(我使用 provider 来管理我的应用范围的状态)。
例如:以下所有变量和方法仅属于此页面和子小部件 将它们置于应用程序范围内的状态是没有意义的。 (如页面,并获取下一页进行分页)
然而,将它们放置在有状态的小部件中确实会混合 UI 和逻辑,这是我试图避免的。
class UpdatesScreen extends StatefulWidget {
static const String routeName = '/announcements';
@override
_UpdatesScreenState createState() => _UpdatesScreenState();
}
class _UpdatesScreenState extends State<UpdatesScreen> {
final _scrollController = ScrollController();
final _updateRepository = UpdateRepository();
final _utils = FactoryUtils();
int _selectedIndex = 0;
int _page = 1;
int _maxPage = 10000;
bool _isLoading = true;
List<Update> updateList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(),
);
}
Widget _buildBody() {
return Stack(
children: [
Column(
children: [
AnnouncementsPageHeader(),
UpdatesList(
updateList: updateList,
scrollController: _scrollController,
isLoading: _isLoading,
refresh: refresh,
),
],
),
FilterCard(_selectedIndex, selectIndex),
],
);
}
void selectIndex(int index) {
if (index == _selectedIndex) return;
setState(() {
_selectedIndex = index;
updateList = [];
_page = 1;
_maxPage = 10000;
fetchNextPage();
});
}
Future<void> fetchNextPage() async {
if (_page == _maxPage) return;
setState(() => _isLoading = true);
final nextUpdatesResponse = await _updateRepository.getUpdates({
'sort': '-createdAt',
'limit': '10',
'page': _page.toString(),
});
setState(() {
_isLoading = false;
updateList.addAll(nextUpdatesResponse.updates);
_maxPage = nextUpdatesResponse.totalPages;
_page++;
});
}
Future<void> refresh() async {
_page = 1;
await fetchNextPage();
}
}
我想要达到的目标 在有状态小部件的情况下可以访问上下文和 setState 函数的控制器
class UpdateScreenController {
int page = 0;
void incrementPage() {
// this function has access to the context for accessing app wide state api
// this function has access to setState to refresh the page when needed
}
}
所以它可以像这样与小部件一起使用
class UpdateScreen extends StatelessWidget {
final controller = UpdatesController();
@override
Widget build(BuildContext context) {
return Container(
// Accessing the data using controller object
color: Text(controller.page),
);
}
}