我在LayoutBuilder中有一个PageView来获取小部件的大小。 由于它取决于窗口小部件的大小,因此在构建窗口小部件之前,我不知道会有多少页面。因此,我在LayoutBuilder中添加了FutureBuilder,因此可以异步计算页面数。这是我的代码,但是它在ConnectionState.waiting中无限期地等待。 代码中有什么问题以及如何解决?
PATCH
答案 0 :(得分:2)
FutureBuilder
的文档指出,您不应该在每个版本上都创建未来:https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
要么在getPageCount
中的initState
中,在字段初始化程序中运行,要么准备一个类似于FutureBuilder
的有状态小部件,该小部件将使用将来的创建函数并在自己的{{1 }}。
答案 1 :(得分:1)
您不应该在FutureBuilder
中使用LayoutBuilder
。可能会多次调用该构建器,因此将来每次都会调用一次。用户界面更新后,LayoutBuilder
中的构建器将被调用。例如,如果您从纵向更改为横向,则将其称为建造者两次,因此也称为将来。
答案 2 :(得分:0)
getPageCount()
构建时都会调用 LayoutBuilder
。
我修改了您的代码,现在每页调用一次该函数。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: ScrollableTabsDemo());
}
}
class _Page {
const _Page({this.icon, this.text});
final IconData icon;
final String text;
}
const List<_Page> _allPages = <_Page>[
_Page(text: 'tab 1'),
_Page(text: 'tab 2'),
_Page(text: 'tab 3'),
];
class ScrollableTabsDemo extends StatefulWidget {
static const String routeName = '/material/scrollable-tabs';
@override
ScrollableTabsDemoState createState() => ScrollableTabsDemoState();
}
class ScrollableTabsDemoState extends State<ScrollableTabsDemo>
with SingleTickerProviderStateMixin {
TabController _controller;
@override
void initState() {
super.initState();
_controller = TabController(vsync: this, length: _allPages.length);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final Color iconColor = Theme.of(context).accentColor;
return Scaffold(
appBar: AppBar(
title: const Text('Scrollable tabs'),
bottom: TabBar(
controller: _controller,
isScrollable: true,
tabs: _allPages.map<Tab>((_Page page) {
return Tab(text: page.text);
}).toList(),
),
),
body: TabBarView(
controller: _controller,
children: _allPages.map<Widget>((_Page page) {
final mFuture = getPageCount();
return SafeArea(
top: false,
bottom: false,
child: LayoutBuilder(builder: (context, constraints) {
return FutureBuilder<int>(
future: mFuture,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
print("none ${snapshot.data}");
return Text('none');
case ConnectionState.active:
print("active ${snapshot.data}");
return Text('active');
case ConnectionState.waiting:
print("waiting ${snapshot.data}");
return Center(child: CircularProgressIndicator());
case ConnectionState.done:
print("done ${snapshot.data}");
return buildPageView(snapshot.data);
}
});
}),
);
}).toList(),
),
);
}
Future<int> getPageCount() => Future.delayed(Duration(seconds: 3), () => 5);
Widget buildPageView(int pageCount) {
return PageView.builder(
itemBuilder: (context, position) {
return Container(child: Center(child: Text(position.toString())));
},
itemCount: pageCount,
);
}
}