Streambuilder 中的 GestureRecognizer 不会更新 snapshot.data


StreamBuilder<String>(
stream: _bloc.urlStream,
builder: (context, snapshot) {
// 1.) url is NOT null here, expected value
final url = snapshot.data;
return RichText(
text: TextSpan(
children: [
// ...
TextSpan(
text: "...",
style: const TextStyle(
color: ThemeColor.lottoRed,
fontWeight: FontWeight.w400,
fontSize: 14,
),
recognizer: TapGestureRecognizer()
..onTap = () {
// 2.) url is null here
},
),
],
),
);
}),

StreamBuilder可以正确获取其快照数据。它开了两次火。第一次snapshot.data为null,第二次它有期望的值(Comment 1.(。如果我点击TextSpan的GestureRecognizerurl仍然为null(Comment 2.(。这里的值没有更新,我该如何解决这个问题?

如果我用一个按钮点击它,它就起作用了,有人能分辨出区别吗。我必须使用TextSpan

StreamBuilder<String>(
stream: _bloc.deregisterUrlStream,
builder: (context, snapshot) {
final url = snapshot.data;

return CustomButton(
action: () {
// url NOT null here, works!
},
text: "testbutton"
);
},
),

我认为问题出在onTap上。

创建一个TapGestureRecognizer作为变量,然后在快照具有Data时设置onTap。

我不太清楚您的解释和代码,因为您没有使用url,也不知道如何请求新数据。在下面的代码中,我使用了您的代码并做了一个示例,希望它能有所帮助。

有一个计数器和一个流,流和计数器由一个启动,每次用户点击文本时,计数器增加一个,文本显示新的数字。

对于流,当它还没有提取时,它返回null,当数据完全提取时,返回它。您可以通过交换机内的snapshot.connectionState处理不同的连接状态,或者只处理两种情况,不管是否有数据。

此外,您还可以将RichText封装在GestureDetector()等其他小部件中。

import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
StreamController<String> stream;
int counter;
@override
void initState() {
counter = 1;
stream = StreamController<String>()..sink.add(counter.toString());
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: _widget(),
),
),
);
}
Widget _widget() {
return StreamBuilder<String>(
stream: stream.stream,
builder: (context, AsyncSnapshot<String> snapshot) {
return (snapshot.hasData)
? RichText(
text: TextSpan(
children: [
TextSpan(
text: snapshot.data,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 50,
),
recognizer: TapGestureRecognizer()
..onTap = () => stream.sink.add((++counter).toString()),
),
],
),
)
: Center(child: CircularProgressIndicator());
},
);
}
@override
void dispose() {
stream.close();
super.dispose();
}
}

最新更新