问题
I have used flutter_offline library to display the offline and online message. The problem is that I want to hide the online message after some time. I can't figure out a way to remove a container when the status is connected but after some duration.
Below is my code:
body: OfflineBuilder(
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget child,
) {
final bool connected = connectivity != ConnectivityResult.none;
return SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: const EdgeInsets.all(0.0),
child: Column(
children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
child: connected
? Container(
color: Colors.lightGreenAccent[400],
height: 25,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'ONLINE',
style: TextStyle(color: Colors.black),
),
],
))
: Container(
color: Colors.red,
height: 25,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'OFFLINE',
style: TextStyle(color: Colors.white),
),
SizedBox(width: 8.0),
SizedBox(
width: 12.0,
height: 12.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white),
),
),
],
),
)),
child,
],
),
);
},
回答1:
Make a bool variable on top of your class. when the connection status change, start a delayed timer and use the empty container to make it invisible after some time.
bool _isContainerVisible = true; // in top of your class
body: OfflineBuilder(
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget child,
) {
final bool connected = connectivity != ConnectivityResult.none;
if(connnected){
Future.delayed(Duration(seconds: 3).then((v){
if(this.mounted)
setState((){
_isContainerVisible = false;
});
});
}
return SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: const EdgeInsets.all(0.0),
child: Column(
children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
child: connected
? _isContainerVisible ?Container(
color: Colors.lightGreenAccent[400],
height: 25,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'ONLINE',
style: TextStyle(color: Colors.black),
),
],
)):Container()
: Container(
color: Colors.red,
height: 25,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'OFFLINE',
style: TextStyle(color: Colors.white),
),
SizedBox(width: 8.0),
SizedBox(
width: 12.0,
height: 12.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white),
),
),
],
),
)),
child,
],
),
);
},
回答2:
You have to use Visibility
and Future.duration
in order to achieve this. Wrap the Widget you want to hide with the Visibility
widget.
Invisible (takes up space):
Visibility(
child: Text("Invisible"),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _visible,
),
Gone (doesn't take up space):
Visibility(
child: Text("Offline"), //Your widget is gone and won't take up space
visible: _visible,
),
For hiding the widget after some time:
@override
void initState() {
super.initState(); //when this route starts, it will execute this code
Future.delayed(const Duration(seconds: 5), () { //asynchronous delay
if (this.mounted) { //checks if widget is still active and not disposed
setState(() { //tells the widget builder to rebuild again because ui has updated
_visible=false; //update the variable declare this under your class so its accessible for both your widget build and initState which is located under widget build{}
});
}
});
}
来源:https://stackoverflow.com/questions/60798709/easy-way-to-hide-a-widget-after-some-duration-in-flutter