我正在这样使用StreamBuilder
-
StreamController streamController = StreamController.broadcast();
StreamBuilder(
stream: streamController.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return (snapshot.hasData == true) //THIS CONDITION!!!
? CircularProgressIndicator()
: myWidget();
)
我正在这样添加到我的信息流中-
onPressed: () {
streamController.add(null);
},
我无法理解应该显示进度指示器或窗口小部件的情况。由于我没有传递任何数据,因此无法使用hasData
。我尝试传递伪数据,但是hasData
永远不会变为假(即使异步函数结束后也是如此)。
我尝试使用connectionState
,但这始终处于活动状态。我不知道为什么它没有变为waiting
状态。当我使用FutureBuilder
时会这样做。 (我以为我可以检查状态是否为waiting
,显示进度指示器,但这不起作用。为什么??
请帮助。
答案 0 :(得分:1)
当我有一个异步调用返回我未来的数据时,也需要此响应来使用我认为是BLoC模式的流更新我的UI层。需要更多的代码,但是它将简化您的问题,并使您的代码更具可读性,可伸缩性,并且像其他操作一样,将流和异步调用从UI代码中排除。
您的情况很简单:
CuPy Version : 5.4.0
CUDA Root : /usr/local/cuda-10.1
CUDA Build Version : 10010
CUDA Driver Version : 0
CUDA Runtime Version : CUDARuntimeError('cudaErrorInsufficientDriver: CUDA driver version is insufficient for CUDA runtime version',)
cuDNN Build Version : 7500
cuDNN Version : 7500
NCCL Build Version : None
NCCL Runtime Version : None
通过示例来跟踪enum DownloadState { NO_DOWNLOAD, DOWNLOADING, SUCCESS }
调用网络API调用的状态的枚举。
async
一个BLoC类,它公开了一个流,并且在该类内部,我们创建了一个通过示例调用Network API的方法,当获取结果时,我们可以保存值,转换此值,使用流和其他方式发送到UI。在这里,在class Bloc {
final ApiClass api = new ApiClass(); // simulating your downloader object
final StreamController controller = StreamController<DownloadState>.broadcast();
Stream get dataState => controller.stream; // exposing your stream output
void _changeState( final DownloadState state ) => controller.sink.add( state );
void downloadData(){
_changeState( DowloadState.DOWNLOADING );
// assuming that this call returns a Future object.
api.downloadData().then( (yourNetworkData) {
// handle your downloaded data
_changeState( DownloadState.SUCCESS );
} ).catchError( (apiError) => controller.sink.addError( apiError ); );
}
}
中,完成Future对象之后,我们将一个downloadData
值放入流中,这将迫使正在监听controller.stream的小部件在DownloadState
帮助下在UI层中重建。如果我们从网络调用中收到一些错误,我们会将其放入流错误输出StreamBuilder
中,并在UI层中使用controller.sink.addError
属性进行检查。
在您的UI层中...
snapshot.hasError
和onPress事件中
Bloc bloc = Bloc(); // you can create a instance of BLoC in initState or in widget contructor...
StreamBuilder<DownloadState>(
stream: bloc.dataState, // bloc get method that returns stream output.
initialData: DownloadState.NO_DOWNLOAD. // this will be the inital value. It's optional
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData){
switch(snapshot.data){
case DownloadState.NO_DOWNLOAD:
return NoDownloadWidget();
case DownloadState.DOWNLOADING:
return CircularProgressIndicator();
case DownloadState.SUCCESS:
return myWidget();
}
}
return ErrorWidget( snapshot.error );
)
使用这种方法,您可以删除UI层流对象和控制器,不需要setState调用,您将拥有一个包含业务逻辑和外部api调用的特定文件,这可以使我们拥有这种工作更加容易期货和信息流一起工作。
我希望能帮上忙。