flutter - Flutter - 如何正确创建一个内部有微调器的按钮小部件以隔离 setState 调用?
问题描述
我有一个可重用的有状态小部件,它返回一个按钮布局。当网络调用正在进行时,按钮文本变为加载微调器,并在网络请求完成时变为文本。
我可以showSpinner
从小部件外部传递一个参数,但这需要在小部件外部调用 setState,这会导致其他小部件的重建。
所以我需要从按钮小部件内部调用 setState 。
我还将回调作为参数传递给按钮小部件。有没有办法将微调器更改状态设置隔离到这样的小部件内部,以便它仍然可以重用?
解决方案
你可以用它StreamBuilder
来解决这个问题。
首先,我们需要创建一个stream
. 创建一个新文件来存储它,我们将其命名banana_stream.dart
,例如;)。
class BananaStream{
final _streamController = StreamController<bool>();
Stream<bool> get stream => _streamController.stream;
void dispose(){
_streamController.close();
}
void add(bool isLoading){
_streamController.sink.add(isLoading);
}
}
要访问它,您应该使用Provider
, 因此添加一个Provider
作为Widget
包含可重用按钮的父级。
Provider<BananaStream>(
create: (context) => BananaStream(),
dispose: (context, bloc) => bloc.dispose(),
child: YourWidget(),
),
然后添加StreamBuilder
到您的按钮小部件:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<bool>(
stream: Provider.of<BananaStream>(context, listen:false),
initialData: false,
builder: (context, snapshot){
final isLoading = snapshot.data;
if(isLoading == false){
return YourButtonWithNoSpinner();
} else{
return YourButtonWithSpinner();
}
}
);
}
}
要更改 isLoading 外部,您可以使用以下代码:
final provider = Provider.of<BananaStream>(context, listen:false);
provider.add(true); //here is where you change the isLoading value
而已!
或者,您可以使用ValueNotifier
orChangeNotifier
但我发现它很难实现。
推荐阅读
- java - Kotlin:如何获取文件(IMAGE)的创建日期?
- laravel - 在 laravel 6.3 中显示调用未定义函数 setActive() 错误
- reactjs - 使用 firebase 创建两种不同类型的用户身份验证
- .net - 如何将 Webflow 制作的前端集成到 .NET Core 中?
- html - 将形状放在图标后面作为悬停状态
- azure - Terragrunt 是否可用于 Azure?
- javascript - 当我导入 React Router 时,Webpack 显示警告
- ubuntu - 在 ubuntu 服务器上使用 nginx 来自 namecheap 的 ssl 证书问题
- php - 如何在 laravel Milldeware 中向具有特定角色的用户验证特定路由
- javascript - 带有一半背景图像的页脚