#flutter #dart #flutter-test
Вопрос:
У меня есть конструктор потоков, но он показывает другой запрос потока, который зависит от выбора пользователя.
При использовании изменений выбора возникает проблема, связанная с небольшой задержкой между получением потокового запроса выбора, поэтому очень кратко отображается предыдущий запрос и сразу же изменяется выбранный запрос. Мне интересно, есть ли какой-либо способ предотвратить отображение запроса в течение этого времени задержки.
body: ListView(
children: <Widget>[
select(),// decide buyOrSell
StreamBuilder(
stream: buyOrSell == "buy"
? FirebaseFirestore.instance
.collection("buy")
.doc(widget.profileId)
.collection("barter")
.orderBy('timestamp', descending: true)
.snapshots()
: FirebaseFirestore.instance
.collection("sell")
.doc(widget.profileId)
.collection("barter")
.orderBy('timestamp', descending: true)
.snapshots(),
Ответ №1:
Обратитесь к официальной документации StreamBuilder: https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html#widgets.Потокостроитель.1
Внутри метода StreamBuilder builder есть значение AsyncSnapshot, которое содержит не только данные потока, но также состояние и ошибки. Внутри вашего метода построения проверьте наличие snapshot.hasError и snapshot.state. Существует 4 состояния соединения:
enum ConnectionState {
/// Not currently connected to any asynchronous computation.
///
/// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
none,
/// Connected to an asynchronous computation and awaiting interaction.
waiting,
/// Connected to an active asynchronous computation.
///
/// For example, a [Stream] that has returned at least one value, but is not
/// yet done.
active,
/// Connected to a terminated asynchronous computation.
done,
}
Ваша «задержка» вызвана переключениями между этими состояниями, поэтому в идеале вам нужно указать возврат для каждого состояния. См. Полный пример, взятый из документации:
return Scaffold(
body: ListView(
children: <Widget>[
select(), // decide buyOrSell
StreamBuilder(
stream: buyOrSell == "buy"
? FirebaseFirestore.instance
.collection("buy")
.doc(widget.profileId)
.collection("barter")
.orderBy('timestamp', descending: true)
.snapshots()
: FirebaseFirestore.instance
.collection("sell")
.doc(widget.profileId)
.collection("barter")
.orderBy('timestamp', descending: true)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
List<Widget> children;
if (snapshot.hasError) {
children = <Widget>[
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text('Stack trace: ${snapshot.stackTrace}'),
),
];
} else {
switch (snapshot.connectionState) {
case ConnectionState.none:
children = const <Widget>[
Icon(
Icons.info,
color: Colors.blue,
size: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Select a lot'),
)
];
break;
case ConnectionState.waiting:
children = const <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting bids...'),
)
];
break;
case ConnectionState.active:
children = <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('${snapshot.data}'),
)
];
break;
case ConnectionState.done:
children = <Widget>[
const Icon(
Icons.info,
color: Colors.blue,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('${snapshot.data} (closed)'),
)
];
break;
}
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
);
},
),
],
),
);