flutter - 如何直接将块添加到视图小部件
问题描述
我有一个创建小部件的屏幕。
如何将块添加到我的小部件?
class UserView extends StatelessWidget {
final AnimationController aController;
final Animation animation;
@override
Widget build(BuildContext context) {
// Add Scafold here?
return AnimationBuilder(
animation: aController;
builder: (BuildContext context, Widget child) {
...
},
);
}
}
集团
class UserBloc extends Bloc<UserEvent, UserState> {
final UserRepo userRepo;
UserBloc({@required this.userRepo}) : assert(userRepo != null);
}
如果我添加一个Scaffold()
然后我得到一个错误说“对象在布局期间被赋予了无限大小”。
我正在将此https://bloclibrary.dev/#/用于 bloc。
如有必要,我可以显示更多代码,我试图保持简洁以便于阅读。请询问,我可以添加更多。
应用程序
void main() async {
final UserRepo userRepo = UserRepo();
BlocSupervisor.delegate = SimpleBlocDelegate();
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]).then((_) => runApp(MultiBlocProvider(
providers: [
BlocProvider<UserBloc>(
create: (context) => UserBloc(userRepo: userRepo),
)
],
child: MyApp(),
)));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: AppTheme.textTheme,
platform: TargetPlatform.iOS,
),
home: HomeScreen(),
);
}
}
主屏幕
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with TickerProviderStateMixin {
AnimationController animationController;
Widget tabBody = Container(
color: AppTheme.background,
);
@override
void initState() {
animationController = AnimationController(
duration: const Duration(milliseconds: 800), vsync: this);
tabBody = DashboardScreen(animationController: animationController);
super.initState();
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: AppTheme.background,
child: Scaffold(
backgroundColor: Colors.transparent,
body: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return Stack(
children: <Widget>[
tabBody
],
);
}
},
),
),
);
}
}
仪表盘
class DashboardScreen extends StatefulWidget {
const DashboardScreen({Key key, this.animationController}) : super(key: key);
final AnimationController animationController;
@override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen>
with TickerProviderStateMixin {
Animation<double> topBarAnimation;
List<Widget> listViews = <Widget>[];
final ScrollController scrollController = ScrollController();
double topBarOpacity = 0.0;
@override
void initState() {
listViews.add(
UserView(
animation: Tween<double>(begin: 0.0, end: 1.0).animate(CurvedAnimation(
parent: widget.animationController,
curve:
Interval((1 / count) * 1, 1.0, curve: Curves.fastOutSlowIn))),
animationController: widget.animationController,
),
);
super.initState();
}
}
解决方案
我认为这UserBloc
必须对整个应用程序可用,如果没有,只需将以下提供者的级别更改为刚好高于它应该覆盖的小部件:
在这里,您提供要在MaterialApp
小部件上方的块以便稍后在此小部件的任何后代中使用它:(在 App 文件中)
return BlocProvider(
create: (_)=>UserBloc(userRepo:UserRep()),
child: MaterialApp(
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: AppTheme.textTheme,
platform: TargetPlatform.iOS,
),
home: HomeScreen(),
),
);
现在,如果您想使用您的 bloc 来发出事件并侦听 的任何后代小部件中的状态MaterialApp
,您只需用BlocListener
orBlocConsumer
或 or包装该小部件(请参阅它们之间的BlocBuilder
区别):
我想你想这样做HomeScreen
:
class _HomeScreenState extends State<HomeScreen>
with TickerProviderStateMixin {
AnimationController animationController;
Widget tabBody = Container(
color: AppTheme.background,
);
@override
void initState() {
animationController = AnimationController(
duration: const Duration(milliseconds: 800), vsync: this);
tabBody = DashboardScreen(animationController: animationController);
super.initState();
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: AppTheme.background,
child: Scaffold(
backgroundColor: Colors.transparent,
body: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return Stack(
children: <Widget>[
//tabBody
//Don't save widgets as fields, just create them on the fly
BlocBuilder<UserBloc,UserState>(
builder: (ctx,state){
//return widget that depends on state and which should rebuild when state changes
return DashboardScreen(animationController: animationController);
},
)
],
);
}
},
),
),
);
}
}
就是这样。
检查上面的链接以获取更多文档。
推荐阅读
- javascript - 使用 Javascript 从浏览器调用 AWS Lambda,如何将输入值发送到函数?
- javascript - 使用图像作为超链接并保存文本框输入值?
- tensorflow - 在 GPU 上运行 CNN 时,用于深度强化学习的 CPU 模拟会导致延迟问题
- c++ - 如何在数组列表 C++ 中来回移动?
- variables - 詹金斯在窗户上。声明性管道 jenkinsfile。如何设置和获取正确的变量值
- excel - 应用程序等待时间问题
- reactjs - MobX + 反应。有人可以展示一些真正有用的自动运行、拦截器和观察案例吗?
- java - 多线程环境初始化前读取非最终字段的代码演示
- azure-web-app-service - 发布更改后强制重新加载 Blazor 客户端
- google-sheets - 两次使用过滤器公式的结果