Flutter 从API获取数据时如何显示进度指示器?

Flutter 从API获取数据时如何显示进度指示器?,flutter,stream,bloc,flutter-widget,progress-indicator,Flutter,Stream,Bloc,Flutter Widget,Progress Indicator,问题很简单,但我找不到合适的解决办法。我有一个搜索屏幕,下面是我想做的 当屏幕第一次启动时,我想在Textwidget“您的结果将显示在此处”中显示一条消息 如果用户在搜索框中输入内容并按search,我想显示循环压缩器指示器 然后,当收到API响应时,我想显示一个列表视图或文本,说“找不到任何东西” 如果用户再次搜索某个内容,我想再次显示CircularProgressIndicator 如何使用流实现此行为?以下是我目前的代码: 小部件 StreamBuilder<List<

问题很简单,但我找不到合适的解决办法。我有一个搜索屏幕,下面是我想做的

  • 当屏幕第一次启动时,我想在
    Text
    widget“您的结果将显示在此处”中显示一条消息
  • 如果用户在搜索框中输入内容并按search,我想显示
    循环压缩器指示器
  • 然后,当收到API响应时,我想显示一个
    列表视图
    文本
    ,说“找不到任何东西”
  • 如果用户再次搜索某个内容,我想再次显示
    CircularProgressIndicator
如何使用
实现此行为?以下是我目前的代码:

小部件

StreamBuilder<List<Model>>(
  stream: bloc.searchStream,
  builder: (context, snapshot) {

    if (snapshot.hasError) {
      return Center(
        child: Text(
          'Error occurred'
        ),
      );
    }

    if (!snapshot.hasData) {
      return Center(
        child: Text(
          'Your results will appear here'
        ),
      );
    }

    if (snapshot.hasData && snapshot.data.length < 1) {
      return Center(
        child: Text(
          'Found nothing'
        ),
      );
    }

    // Where should I put my CircularProgressIndicator?

    return ListView.separated(
      itemCount: snapshot.data.length,
      separatorBuilder: (context, index) => Divider(height: 1),
      itemBuilder: (context, index) {
        final item = snapshot.data[index];
        return ItemWidget(item);
      },
    );
  },
)
StreamBuilder(
stream:bloc.searchStream,
生成器:(上下文,快照){
if(snapshot.hasError){
返回中心(
子:文本(
“发生错误”
),
);
}
如果(!snapshot.hasData){
返回中心(
子:文本(
'您的结果将显示在此处'
),
);
}
if(snapshot.hasData&&snapshot.data.length<1){
返回中心(
子:文本(
“什么也没找到”
),
);
}
//我应该把循环压缩机指示器放在哪里?
返回ListView.separated(
itemCount:snapshot.data.length,
separatorBuilder:(上下文,索引)=>分隔符(高度:1),
itemBuilder:(上下文,索引){
最终项目=快照。数据[索引];
返回ItemWidget(项目);
},
);
},
)
集团

final _searchStreamController = StreamController<List<Model>>();
Stream<List<Model>> get searchStream => _searchStreamController.stream;

void search(String searchTerm) async {

  if (searchTerm.isEmpty) {
    _searchStreamController.add(null);
    return;
  }

  final client = HttpClient();
  client.method = HttpMethod.POST;
  client.endPoint = 'search';
  client.addData('query', searchTerm);

  try {
    final responseStr = await client.execute();
    final response = SearchResponse.fromJson(responseStr);
    _searchStreamController.add(response.data);
  } catch (e) {
    _searchStreamController.addError(e);
  }
}
final _searchStreamController = StreamController<JugarModel<List<Data>>>();
Stream<JugarModel<List<Data>>> get searchStream => _searchStreamController.stream;

void search(String searchTerm) async {

  if (searchTerm.isEmpty) {
    _searchStreamController.add(null);
    return;
  }

  final client = HttpClient();
  client.method = HttpMethod.POST;
  client.endPoint = 'search';
  client.addData('query', searchTerm);

  // This MAGIC line will call StreamBuilder callback with isProcessing set to true.
  _searchStreamController.add(JugarModel<List<Data>>(isProcessing: true, data: List()));
  try {
    final responseStr = await client.execute();
    final response = SearchResponse.fromJson(responseStr);

    // And after we've received response from API and parsed it, we're calling StreamBuilder
    // callback again with isProcessing set to false.
    _searchStreamController.add(JugarModel<List<Data>>(isProcessing: false, data: response.data));
  } catch (e) {
    _searchStreamController.addError(e);
  }
}
final\u searchStreamController=StreamController();
Stream get searchStream=>\u searchStreamController.Stream;
无效搜索(字符串搜索术语)异步{
if(searchTerm.isEmpty){
_searchStreamController.add(空);
返回;
}
最终客户机=HttpClient();
client.method=HttpMethod.POST;
client.endPoint='search';
client.addData('query',searchTerm);
试一试{
final responsest=wait client.execute();
最终响应=SearchResponse.fromJson(responsest);
_searchStreamController.add(response.data);
}捕获(e){
_搜索流控制器。加法器(e);
}
}
每次调用
search(String searchedTerm)
函数时,我都要显示
circularproressindicator

谢谢。

StreamBuilder(
    StreamBuilder<List<Model>>(
      stream: bloc.searchStream,
      builder: (context, snapshot) {
 
        if (snapshot.hasData) {
         if (snapshot.data.length ==0){ 
              return  Center(
                 child: Text(
                      'Found nothing'
                    ),
              );
    
            } 
        return ListView.separated(
          itemCount: snapshot.data.length,
          separatorBuilder: (context, index) => Divider(height: 1),
          itemBuilder: (context, index) {
            final item = snapshot.data[index];
            return ItemWidget(item);
          },
        );
        }else if (snapshot.hasError) {
          return Center(
            child: Text(
              'Error occurred'
            ),
          );
      }else {
         return Center(
            child:CircularProgressIndicator()
          );
       }
      },
    )
stream:bloc.searchStream, 生成器:(上下文,快照){ if(snapshot.hasData){ 如果(snapshot.data.length==0){ 返回中心( 子:文本( “什么也没找到” ), ); } 返回ListView.separated( itemCount:snapshot.data.length, separatorBuilder:(上下文,索引)=>分隔符(高度:1), itemBuilder:(上下文,索引){ 最终项目=快照。数据[索引]; 返回ItemWidget(项目); }, ); }else if(snapshot.hasrerror){ 返回中心( 子:文本( “发生错误” ), ); }否则{ 返回中心( 子对象:循环进程指示器() ); } }, )
给出一个初始Text()小部件,其值为“结果将显示在此处”, 然后单击按钮,将初始Text()小部件替换为StreamBuilder,您可以尝试:

StreamBuilder<List<Model>>(
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Center(child: Text('Your results will appear here'));

              case ConnectionState.active:
              case ConnectionState.waiting:
                return Center(child: CircularProgressIndicator());

              case ConnectionState.done:
                if (snapshot.hasError)
                  return Center(child: Text('Error occurred'));

                if (snapshot.data.isEmpty) {
                  return Container(child: Center(child: Text('Found nothing')));
                } else {
                  return ListView.separated(
                    itemCount: snapshot.data.length,
                    separatorBuilder: (context, index) => Divider(height: 1),
                    itemBuilder: (context, index) {
                      final item = snapshot.data[index];
                      return ItemWidget(item);
                    },
                  );
                }
            }
            return Center(child: Text('Your results will appear here'));
          },
        )
StreamBuilder(
生成器:(上下文,快照){
交换机(快照.连接状态){
案例连接状态。无:
返回中心(child:Text(“您的结果将显示在此处”);
案例连接状态.active:
案例连接状态。正在等待:
返回中心(子项:CircularProgressIndicator());
案例连接状态。完成:
if(snapshot.hasError)
返回中心(子项:文本(“发生错误”);
if(snapshot.data.isEmpty){
返回容器(子:中心(子:文本('foundnothing'));
}否则{
返回ListView.separated(
itemCount:snapshot.data.length,
separatorBuilder:(上下文,索引)=>分隔符(高度:1),
itemBuilder:(上下文,索引){
最终项目=快照。数据[索引];
返回ItemWidget(项目);
},
);
}
}
返回中心(child:Text(“您的结果将显示在此处”);
},
)

以下是我为了达到我的要求而必须做的事情。如果有更好的方法来实现这一点,请张贴一个答案,我会标记为正确

黑客

class JugarModel<T> {
  bool isProcessing;
  T data;

  JugarModel({this.isProcessing, this.data});
}
集团

final _searchStreamController = StreamController<List<Model>>();
Stream<List<Model>> get searchStream => _searchStreamController.stream;

void search(String searchTerm) async {

  if (searchTerm.isEmpty) {
    _searchStreamController.add(null);
    return;
  }

  final client = HttpClient();
  client.method = HttpMethod.POST;
  client.endPoint = 'search';
  client.addData('query', searchTerm);

  try {
    final responseStr = await client.execute();
    final response = SearchResponse.fromJson(responseStr);
    _searchStreamController.add(response.data);
  } catch (e) {
    _searchStreamController.addError(e);
  }
}
final _searchStreamController = StreamController<JugarModel<List<Data>>>();
Stream<JugarModel<List<Data>>> get searchStream => _searchStreamController.stream;

void search(String searchTerm) async {

  if (searchTerm.isEmpty) {
    _searchStreamController.add(null);
    return;
  }

  final client = HttpClient();
  client.method = HttpMethod.POST;
  client.endPoint = 'search';
  client.addData('query', searchTerm);

  // This MAGIC line will call StreamBuilder callback with isProcessing set to true.
  _searchStreamController.add(JugarModel<List<Data>>(isProcessing: true, data: List()));
  try {
    final responseStr = await client.execute();
    final response = SearchResponse.fromJson(responseStr);

    // And after we've received response from API and parsed it, we're calling StreamBuilder
    // callback again with isProcessing set to false.
    _searchStreamController.add(JugarModel<List<Data>>(isProcessing: false, data: response.data));
  } catch (e) {
    _searchStreamController.addError(e);
  }
}
final\u searchStreamController=StreamController();
Stream get searchStream=>\u searchStreamController.Stream;
无效搜索(字符串搜索术语)异步{
if(searchTerm.isEmpty){
_searchStreamController.add(空);
返回;
}
最终客户机=HttpClient();
client.method=HttpMethod.POST;
client.endPoint='search';
client.addData('query',searchTerm);
//此魔线将在isProcessing设置为true时调用StreamBuilder回调。
_添加(JugarModel(isProcessing:true,data:List());
试一试{
final responsest=wait client.execute();
最终响应=SearchResponse.fromJson(responsest);
//在收到API的响应并对其进行解析后,我们将调用StreamBuilder
//在isProcessing设置为false时再次回调。
_searchStreamController.add(JugarModel(isProcessing:false,data:response.data));
}捕获(e){
_搜索流控制器。加法器(e);
}
}

这不起作用。因为它开始在start中显示
CircularProgressIndicator
。我想去购物