我有一个应用程序,在首页中产品水平显示。点击产品后,将显示产品详细信息屏幕,其中有关产品的详细信息显示在不同的小部件中。
此详细信息屏幕还具有显示相关产品的水平滚动列表。轻触其中一个相关产品后,将显示相同详细信息屏幕的另一个实例。
问题
但是这里的问题是build方法被调用了两次。仅当我尝试查看相关产品的详细信息时(它在产品详细信息页面本身中列出),它两次调用。
这是Details
屏幕中代码的一部分。
class Details extends StatefulWidget {
// Declare a field that holds the Todo.
final details;
// In the constructor, require a Todo.
Details({Key key, @required this.details}) : super(key: key);
State<StatefulWidget> createState() {
return _DetailsState(details);
}
}
class _DetailsState extends State<Details> with SingleTickerProviderStateMixin {
_DetailsState(details);
YoutubePlayerController _ytcontroller;
TabController _tabController;
int _tabIndex = 0;
Screen size;
@override
void dispose() {
if (_ytcontroller != null) {
_ytcontroller.dispose();
}
_tabController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
if (widget.details.videos != null) {
String videoId;
videoId = YoutubePlayer.convertUrlToId(widget.details.videos[0].url);
_ytcontroller = YoutubePlayerController(
initialVideoId: videoId,
flags: YoutubePlayerFlags(
mute: false,
autoPlay: true,
disableDragSeek: false,
loop: false,
isLive: false,
forceHideAnnotation: true,
),
);
_tabController = TabController(length: 4, vsync: this);
} else {
_tabController = TabController(length: 3, vsync: this);
}
_tabController.addListener(_handleTabSelection);
}
_handleTabSelection() {
if (_tabController.indexIsChanging) {
setState(() {
_tabIndex = _tabController.index;
});
}
}
@override
Widget build(BuildContext context) {
String wid = widget.details.itemId;
//IF I PUT DEBUG MARKER ABOVE AND TAP RELATED PRODUCT FROM PRODUCT DETAILS PAGE
//THIS BUILD METHOD GETS CALLED TWO TIMES,
// FIRST => wid = item id of clicked product
// SECOND => wid = item id of currently viewing product
size = Screen(MediaQuery.of(context).size);
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Constants.scaffoldColor,
floatingActionButton: buildBoomMenu(widget.details),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: size.getSizePx(277),
floating: false,
title: const Text("Details"),
pinned: true,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Constants.gradientStart, Constants.gradientEnd]),
),
child: FlexibleSpaceBar(
centerTitle: true,
background: Swiper(
itemBuilder: (BuildContext context, int index) {
return _cacheImageBuilder(
widget.details.images[index].thumb);
},
itemCount: widget.details.images.length,
pagination: new SwiperPagination(
alignment: Alignment.bottomCenter,
builder: FractionPaginationBuilder(
activeColor: Colors.white,
color: Colors.white70,
fontSize: size.getSizePx(16),
activeFontSize: size.getSizePx(20),
),
),
autoplay: true,
onTap: (index) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageViewer(
imglists: widget.details.images,
initialIndex: index,
),
),
);
},
autoplayDelay: 8000,
autoplayDisableOnInteraction: true,
),
),
),
),
];
},
body: SingleChildScrollView(
padding: EdgeInsets.only(
left: size.getSizePx(10), right: size.getSizePx(10)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
//height: size.getSizePx(230),
child: propertyDetails(),
),
TabBar(
controller: _tabController,
labelStyle: TextStyle(fontSize: size.getSizePx(12)),
labelColor: Constants.primaryColor,
unselectedLabelColor: Colors.black45,
indicatorColor: Constants.primaryColor,
tabs: [
Tab(
text: "Seller Info",
icon: Icon(Constants.iconAccount),
),
Tab(
text: "Details",
icon: Icon(Constants.iconDetails),
),
Tab(text: "Video", icon: Icon(Constants.iconYoutube)),
],
),
Container(
child: [
Container(
margin: EdgeInsets.only(top: size.getSizePx(15)),
child: Column(
children: <Widget>[
//Show some widgets
],
),
),
Container(
margin: EdgeInsets.only(top: size.getSizePx(15)),
child: Column(
children: <Widget>[
//show few widgets here
],
),
),
Container(
//show videos
),
][_tabIndex],
),
const SizedBox(height: 20),
RelatedProducts( //Another widget which fetches list of products related to product whose detail we are currently viewing
deviceType: "mobile",
model: widget.details.model,
sku: widget.details.sku,
category: widget.details.category,
itemId: widget.details.itemId,
brand: widget.details.brand,
),
SizedBox(height: size.getSizePx(40)),
],
),
),
),
);
}
}
有人可以帮我吗?
答案 0 :(得分:0)
build方法被称为evreytime,状态会发生变化(包括导航),但是正如我所看到的,您正在尝试在build方法中获取屏幕尺寸evreytime,因此我创建了这个库,该库可能对您有帮助{{3 }}。