很抱歉,如果标题有误导性,那就不能写出更好的标题了。
我有一个应用程序,其中产品在水平列表视图中列出。点击每个产品后,我们可以看到其详细信息。 详细信息页面显示所选产品的详细信息以及相关产品的水平列表。
问题
我是新手,不知道发生了什么事。有人可以帮我吗?
我有以下产品详细信息屏幕
product_details.dart
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)),
],
),
),
),
);
}
}
和相关产品小部件
related_products.dart
class RelatedProducts extends StatefulWidget {
final String deviceType;
final String model;
final String sku;
final String category;
final String itemId;
final String brand;
// In the constructor, require a Todo.
RelatedProducts(
{Key key,
@required this.deviceType,
@required this.model,
@required this.sku,
@required this.category,
@required this.itemId,
@required this.brand})
: super(key: key);
State<StatefulWidget> createState() {
return _RelatedProductsState(
deviceType, model, sku, category, itemId, brand);
}
}
class _RelatedProductsState extends State<RelatedProducts> {
_RelatedProductsState(String deviceType, String model, String sku,
String category, String itemId, String brand);
final ScrollController scrollController = new ScrollController();
Stream<RelatedProductsModel> _bloc;
Screen size;
List productList = List();
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
@override
void initState() {
Map data = {
"device_type": "mobile",
"model": widget.model,
"category": widget.category,
"sku": widget.sku,
"itemId": widget.itemId,
"brand": widget.brand
};
bloc.fetchRelatedProducts(data);
_bloc = bloc.allRelatedProps;
WidgetsBinding.instance.addPostFrameCallback((_) => _noRelatedProducts());
super.initState();
}
@override
Widget build(BuildContext context) {
size = Screen(MediaQuery.of(context).size);
return Column(
children: <Widget>[
SizedBox(
height: size.getSizePx(25),
),
LeftAlignedText(
text: "Related Products",
leftPadding: 0,
textColor: textPrimaryColor,
overflow: TextOverflow.visible,
fontSize: 18.0),
Container(
padding: EdgeInsets.only(top: size.getSizePx(10)),
height: size.getSizePx(240),
child: _buildStream(),
)
],
);
}
StreamBuilder _buildStream() {
return StreamBuilder<RelatedProductsModel>(
stream: _bloc,
builder: (context, AsyncSnapshot<RelatedProductsModel> snapshot) {
if (snapshot.hasData) {
return buildPropListSwipe(snapshot);
} else if (snapshot.hasError) {
return _noRelatedProducts();
}
return _showCircularAnimation();
},
);
}
Widget _noRelatedProducts() {
return Container(
alignment: Alignment.topLeft,
child: Text("No related Products available."),
);
}
Widget buildPropListSwipe(AsyncSnapshot<RelatedProductsModel> snapshot) {
productList = snapshot.data.results;
//returns ListView.Builder
}
}