Flutter 颤振扩展_图像:在生成期间调用setState()或markNeedsBuild()
我正在使用该软件包从网络加载图像,并在加载或出错时显示微光 当我试图在Flutter 颤振扩展_图像:在生成期间调用setState()或markNeedsBuild(),flutter,setstate,dart-pub,statefulwidget,Flutter,Setstate,Dart Pub,Statefulwidget,我正在使用该软件包从网络加载图像,并在加载或出错时显示微光 当我试图在loadStateChanged中调用setState()时,在生成过程中调用了此错误setState()或markNeedsBuild() 事实上,我有两个小部件,一个负责从网络加载缩略图,另一个显示缩略图描述的小部件 但我希望描述显示微光时,图像无法加载或需要更长的时间加载 我在video缩略图小部件上创建了两个状态变量,应该传递给VideoDesc小部件 videoLoading = true; videoError =
loadStateChanged
中调用setState()时,在生成过程中调用了此错误setState()或markNeedsBuild()
事实上,我有两个小部件,一个负责从网络加载缩略图,另一个显示缩略图描述的小部件
但我希望描述显示微光时,图像无法加载或需要更长的时间加载
我在video缩略图
小部件上创建了两个状态变量,应该传递给VideoDesc
小部件
videoLoading = true;
videoError = false;
以下是我的代码,以回购为例:
视频缩略图状态
class\u VideoThumbnailState扩展状态
使用SingleTickerProviderStateMixin{
布尔视频加载;
布尔视频错误;
动画控制器_控制器;
@凌驾
void initState(){
视频加载=真;
videoError=false;
_控制器=动画控制器(
vsync:这个,,
持续时间:常数持续时间(秒数:3),
);
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
打印(“构建过程完成”);
});
}
@凌驾
无效处置(){
_controller.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回容器(
宽度:widget.width,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
ClipRRect(
边界半径:边界半径。圆形(4.0),
子项:ExtendedImage.network(
widget.videoUrl,
宽度:widget.width,
高度:(小部件宽度)*3/4,
loadStateChanged:(ExtendedImageState状态){
开关(state.extendedImageLoadState){
案例LoadState.loading:
_controller.reset();
设置状态(){
videoError=false;
视频加载=真;
});
返回闪烁颜色(
子:容器(
装饰:盒子装饰(
边界半径:边界半径。圆形(4.0),
),
),
基本颜色:颜色。黑色12,
highlightColor:Colors.white24,
);
打破
案例LoadState.completed:
_controller.forward();
设置状态(){
videoError=false;
视频加载=错误;
});
返回衰减转换(
不透明度:_控制器,
子对象:ExtendedRawImage(
image:state.extendedImageInfo?.image,
宽度:widget.width,
高度:(小部件宽度)*3/4,
),
);
打破
案例LoadState.0失败:
_controller.reset();
state.imageProvider.execut();
设置状态(){
videoError=true;
视频加载=错误;
});
返回容器(
宽度:widget.width,
高度:(小部件宽度)*3/4,
装饰:盒子装饰(
图像:装饰图像(
图像:AssetImage(“assets/img/notfound.png”),
fit:BoxFit.fill,
),
),
);
打破
违约:
返回容器();
}
},
),
),
视频描述(
desc:widget.desc,
videoError:videoError,
视频加载:视频加载,
)
],
),
);
}
}
视频小部件
classvideodesc扩展了无状态小部件{
最终字符串描述;
最终布尔视频加载;
最终布尔视频错误;
常数视频描述({
关键点,
@需要这个.desc,
this.videoLoading=true,
this.videoError=false,
}):super(key:key);
@凌驾
小部件构建(构建上下文){
返回容器(
孩子:视频错误| |视频加载
?微光颜色(
基色:颜色。灰色[700],
highlightColor:Colors.white24,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
尺寸箱(高度:12.0),
容器(
宽度:double.infinity,
身高:8.0,
装饰:盒子装饰(
颜色:颜色。灰色[900],
边界半径:边界半径。圆形(2.0),
),
),
尺寸箱(高度:12.0),
容器(
宽度:80.0,
身高:8.0,
装饰:盒子装饰(
颜色:颜色。灰色[900],
边界半径:边界半径。圆形(2.0),
),
),
],
),
)
:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
尺寸箱(高度:12.0),
正文(
描述,
样式:TextStyle(
颜色:颜色,白色,
字体大小:11.0,
),
溢出:
class _VideoThumbnailState extends State<VideoThumbnail>
with SingleTickerProviderStateMixin {
bool videoLoading;
bool videoError;
AnimationController _controller;
@override
void initState() {
videoLoading = true;
videoError = false;
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 3),
);
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
print("Build Process Complete");
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: widget.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: ExtendedImage.network(
widget.videoUrl,
width: widget.width,
height: (widget.width) * 3 / 4,
loadStateChanged: (ExtendedImageState state) {
switch (state.extendedImageLoadState) {
case LoadState.loading:
_controller.reset();
setState(() {
videoError = false;
videoLoading = true;
});
return Shimmer.fromColors(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
),
),
baseColor: Colors.black12,
highlightColor: Colors.white24,
);
break;
case LoadState.completed:
_controller.forward();
setState(() {
videoError = false;
videoLoading = false;
});
return FadeTransition(
opacity: _controller,
child: ExtendedRawImage(
image: state.extendedImageInfo?.image,
width: widget.width,
height: (widget.width) * 3 / 4,
),
);
break;
case LoadState.failed:
_controller.reset();
state.imageProvider.evict();
setState(() {
videoError = true;
videoLoading = false;
});
return Container(
width: widget.width,
height: (widget.width) * 3 / 4,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/img/not-found.png"),
fit: BoxFit.fill,
),
),
);
break;
default:
return Container();
}
},
),
),
VideoDesc(
desc: widget.desc,
videoError: videoError,
videoLoading: videoLoading,
)
],
),
);
}
}
class VideoDesc extends StatelessWidget {
final String desc;
final bool videoLoading;
final bool videoError;
const VideoDesc({
Key key,
@required this.desc,
this.videoLoading = true,
this.videoError = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: videoError || videoLoading
? Shimmer.fromColors(
baseColor: Colors.grey[700],
highlightColor: Colors.white24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 12.0),
Container(
width: double.infinity,
height: 8.0,
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(2.0),
),
),
SizedBox(height: 12.0),
Container(
width: 80.0,
height: 8.0,
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(2.0),
),
),
],
),
)
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 12.0),
Text(
desc,
style: TextStyle(
color: Colors.white,
fontSize: 11.0,
),
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 5.0),
Text(
"361,143,203 views",
style: TextStyle(
color: Colors.white54,
fontSize: 12.0,
),
),
],
),
);
}
}
WidgetsBinding.instance.addPostFrameCallback(() => setState((){}));
if(!videoLoading) {
WidgetsBinding.instance.addPostFrameCallback(() => setState((){
videoError = false;
videoLoading = true;
}));
}