在 Flutter 中持续一段时间后隐藏小部件的简单方法
Easy way to hide a widget after some duration in Flutter
我使用了flutter_offline库来显示离线和在线消息。问题是我想在一段时间后隐藏在线消息。当状态已连接但持续一段时间后,我想不出一种方法来删除容器。
下面是我的代码:
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,
],
),
);
},
在你的 class 之上创建一个 bool 变量。当连接状态改变时,启动一个延迟定时器,并使用空容器使其在一段时间后不可见。
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,
],
),
);
},
您必须使用 Visibility
和 Future.duration
才能实现此目的。用 Visibility
小部件包裹要隐藏的小部件。
选项 1 - 不可见(占用 space):
Visibility(
child: Text("Invisible"),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _visible,
),
选项 2 - 已删除(不占用 space):
Visibility(
child: Text("Offline"), //Your widget is gone and won't take up space
visible: _visible,
),
一段时间后隐藏小部件:
@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{}
});
}
});
}
我使用了flutter_offline库来显示离线和在线消息。问题是我想在一段时间后隐藏在线消息。当状态已连接但持续一段时间后,我想不出一种方法来删除容器。
下面是我的代码:
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,
],
),
);
},
在你的 class 之上创建一个 bool 变量。当连接状态改变时,启动一个延迟定时器,并使用空容器使其在一段时间后不可见。
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,
],
),
);
},
您必须使用 Visibility
和 Future.duration
才能实现此目的。用 Visibility
小部件包裹要隐藏的小部件。
选项 1 - 不可见(占用 space):
Visibility(
child: Text("Invisible"),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _visible,
),
选项 2 - 已删除(不占用 space):
Visibility(
child: Text("Offline"), //Your widget is gone and won't take up space
visible: _visible,
),
一段时间后隐藏小部件:
@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{}
});
}
});
}