我有一个使用SliverChildBuilderDelegate
的SliverList
,我的问题是我不能为SliverList
设置ScrollController
来控制列表滚动,因为我想要控制列表某个特定项的滚动,而在普通的ListView
中,这个任务非常容易完成。我想知道为什么SliverList
没有像ListView
一样的controller
属性?
注意:我知道CustomScrollView
有controller
属性,而我已经测试过了,但这将控制整个视区而不仅仅是列表。
@override
Widget build(BuildContext context) {
MainState m = Provider.of<MainState>(context, listen: false);
return DefaultTabController(
length: m.itemCategoryList.length,
child: Scaffold(
// appBar: _createAppBar(),
body: Builder(builder: (context) => _createBody(context))),
);
}
AppBar _createAppBar() {
MainState m = Provider.of<MainState>(context);
return AppBar(
title: Text(
m.selectedPartner.fullname,
style: Theme.of(context).textTheme.display3,
),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
);
}
_createBody(BuildContext context) {
MainState m = Provider.of<MainState>(context);
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
titleSpacing: 0.0,
elevation: 20.0,
title: Container(
decoration: BoxDecoration(color: Colors.black.withOpacity(0.3)),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
Spacer(
flex: 2,
),
IconButton(
icon: Icon(Icons.info),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
],
),
],
),
),
centerTitle: false,
automaticallyImplyLeading: false,
pinned: true,
bottom: PreferredSize(
// Add this code
preferredSize: Size.fromHeight(10.0), // Add this code
child: Text(''), // Add this code
),
expandedHeight: 250,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
collapseMode: CollapseMode.none,
background: Stack(
children: <Widget>[
Image.network(
m.selectedPartner.imagepath,
fit: BoxFit.cover,
height: 300.0,
width: MediaQuery.of(context).size.width,
color: Colors.black.withOpacity(0.6),
colorBlendMode: BlendMode.darken,
),
Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
m.selectedPartner.fullname,
style: Theme.of(context)
.textTheme
.headline
.copyWith(color: Colors.white),
),
Text(
m.selectedPartner.categorytexts,
style: Theme.of(context)
.textTheme
.title
.copyWith(fontSize: 17.0, color: Colors.white),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 30.0,
decoration: BoxDecoration(color: Colors.white),
child: Row(
children: <Widget>[
Text(
"Delivery time :" +
m.selectedPartner.deliverytime.toString() +
" mins",
style: Theme.of(context).textTheme.subtitle)
],
),
),
)
],
)),
),
SliverPersistentHeader(
delegate: _SliverAppBarDelegate(
TabBar(
isScrollable: true,
labelColor: Colors.black87,
unselectedLabelColor: Colors.black,
tabs: m.itemCategoryList
.map((ele) => Tab(
text: ele.itemcategoryname,
))
.toList(),
),
),
pinned: true,
),
//=========I want to scroll to a specific position in this list
GroupedSliverList(
elements: m.itemList,
groupBy: (ItemModel item) => item.itemcategory_id,
groupSeparatorBuilder: (i, item) => _createGroupItem(i, item),
itemBuilder: (_, item) => _createItem(item)),
],
);
}
_createGroupItem(int categId, ItemModel item) {
MainState m = Provider.of<MainState>(context, listen: false);
ItemCategoryModel categModel =
m.itemCategoryList.firstWhere((ele) => ele.id == categId);
return Container(
child: Text(
categModel.itemcategoryname,
style: Theme.of(context).textTheme.headline,
),
);
}
_createItem(ItemModel item) {
return Card(
elevation: 3.0,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
CircleAvatar(
radius: 30.0,
backgroundImage: NetworkImage(item.imagepath),
),
SizedBox(
width: 18.0,
),
_createDetailColumn(item)
],
),
),
);
}
_createDetailColumn(ItemModel item) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
flex: 1,
child: Row(
children: <Widget>[
Expanded(
child: Text(
item.itemname,
style: Theme.of(context).textTheme.title,
),
),
],
)),
SizedBox(
height: 5.0,
),
Flexible(
flex: 1,
child: Row(
children: <Widget>[
Expanded(
child: Text(
item.description,
style: Theme.of(context).textTheme.subtitle,
),
),
],
),
),
SizedBox(
height: 5.0,
),
SizedBox(
height: 8.0,
),
Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green, width: 1.0),
borderRadius: BorderRadius.circular(10.0)),
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Text(item.price.toString() + " L.E.",
style: Theme.of(context)
.textTheme
.subtitle
.copyWith(color: Colors.green, fontSize: 16.0)),
),
),
],
)
],
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate(this._tabBar);
final TabBar _tabBar;
@override
double get minExtent => _tabBar.preferredSize.height;
@override
double get maxExtent => _tabBar.preferredSize.height;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new Container(
color: Colors.yellow,
child: _tabBar,
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return false;
}
}