不幸的是,在我作为新屏幕的简单代码中,FutureBuilder
可以正常工作并且两次从方法中获取数据!
我不确定出现什么问题以及如何避免该问题
class LessonDetail extends StatefulWidget {
final String monthKey;
final String lessonFileKey;
LessonDetail({@required this.monthKey, @required this.lessonFileKey});
@override
State<StatefulWidget> createState() {
return _LessonDetailState(monthKey, lessonFileKey);
}
}
class _LessonDetailState extends BaseState<LessonDetail> {
String monthKey;
String lessonFileKey;
_LessonDetailState(this.monthKey, this.lessonFileKey);
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
body: FutureBuilder(
future: _getLessonDetail(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
PlayLessonResponse response = snapshot.data;
print(response);
}
return Center(
child: CircularProgressIndicator(),
);
}),
),
);
}
Future<PlayLessonResponse> _getLessonDetail() async {
AudioList audioList = AudioList(
'http://www.sample.com',
'aaaaa'
);
List<AudioList> lst = [audioList,audioList,audioList];
PlayLessonResponse response = PlayLessonResponse(
2,
'',
'http://www.sample.com',
'2',
lst,
1,
'ssss'
);
print('++++++++++++++++++++');
return response;
}
}
BaseState类的内容:
abstract class BaseState<T extends StatefulWidget> extends State {
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult> _connectivitySubscription;
bool isOnline = true;
Future<void> initConnectivity() async {
try {
await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
print(e.toString());
}
if (!mounted) {
return;
}
await _updateConnectionStatus().then((bool isConnected){
if(mounted){
setState(() {
isOnline = isConnected;
});
}
});
}
@override
void initState() {
super.initState();
initConnectivity();
_connectivitySubscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
await _updateConnectionStatus().then((bool isConnected){
if(mounted){
setState(() {
isOnline = isConnected;
});
}
});
});
}
@override
void dispose() {
_connectivitySubscription.cancel();
super.dispose();
}
Future<bool> _updateConnectionStatus() async {
bool isConnected;
try {
final List<InternetAddress> result =
await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isConnected = true;
}
} on SocketException catch (_) {
isConnected = false;
return false;
}
return isConnected;
}
}
输出:
I/flutter (32289): ++++++++++++++++++++
I/flutter (32289): ++++++++++++++++++++
答案 0 :(得分:0)
就像@Ricardo所说的那样,您不应直接在FutureBuilder的future方法内部调用该函数。
相反,您应该首先在init状态下运行函数,并将响应存储在新变量中。只有这样,才能将变量分配给FutureBuilder的未来。
代码示例:
class LessonDetail extends StatefulWidget {
final String monthKey;
final String lessonFileKey;
LessonDetail({@required this.monthKey, @required this.lessonFileKey});
@override
State<StatefulWidget> createState() {
return _LessonDetailState(monthKey, lessonFileKey);
}
}
class _LessonDetailState extends BaseState<LessonDetail> {
String monthKey;
String lessonFileKey;
Future<PlayLesssonResponse> _myResponse; //added this line
_LessonDetailState(this.monthKey, this.lessonFileKey);
@override
void initState() {
_myResponse = _getLessonDetail(); // added this line
super.initState();
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
body: FutureBuilder(
future: _myResponse, //use _myResponse variable here
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
PlayLessonResponse response = snapshot.data;
print(response);
}
return Center(
child: CircularProgressIndicator(),
);
}),
),
);
}
Future<PlayLessonResponse> _getLessonDetail() async {
AudioList audioList = AudioList(
'http://www.sample.com',
'aaaaa'
);
List<AudioList> lst = [audioList,audioList,audioList];
PlayLessonResponse response = PlayLessonResponse(
2,
'',
'http://www.sample.com',
'2',
lst,
1,
'ssss'
);
print('++++++++++++++++++++');
return response;
}
}