ScrollController jumpTo指定值不起作用Flutter
ScrollController jumpTo specified value doesn't work Flutter
在我的应用程序中,我决定显示一个 ScrollBar
,因此 ScrollBar
和 ListView
都需要相同的 ScrollController
我不得不更改我的 ScrollablePositionedList.builder
到 ListView.builder
。
首先在我的 List<Widget> homePageItems
中是 PageView
(因此在索引 0 处),其中包含一些“幻灯片”,然后是其他小部件“内容”,它们是对幻灯片的解释。在每张幻灯片中都有一个按钮,它调用 controller.jumpTo();
以转到幻灯片的说明。
当我使用 ScrollablePositionedList.builder
时,scrollController.jumpTo(index: 5);
按预期工作,跳转到正确的“内容”,但使用 ListView.builder
它不会..它只是移动了几个像素,仅此而已..
有什么我现在设置错误或遗漏的 ListView.builder
?
ListView 项:
List<Widget> homePageItems = [
// carousell index 0
SizedBox(
height: MediaQuery.of(context).size.height > 700 ? MediaQuery.of(context).size.height * 0.89 : MediaQuery.of(context).size.height * 0.85,//580,
width: MediaQuery.of(context).size.width,
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Column(
children: [
Expanded(
child: PageView.builder(
controller: pageController,
onPageChanged: (index) {
timer.cancel();
setState(() {
if (index > _index) {
_current < slides.length -1 ? _current++ : _current = 0;
_index = index;
} else {
_current > 0 ? _current -- : _current = slides.length -1;
_index = index;
}
print('onPageChanged: index is : $index');
print('onPageChanged: _current is : $_current');
});
},
itemBuilder: (context, index){
return slides[_current];
}),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: slides.map((url) {
int index = slides.indexOf(url);
return Container(
width: 5.0,
height: 5.0,
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Colors.redAccent//Color.fromRGBO(0, 0, 0, 0.9)
: Colors.black54,//Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
],
),
Row(
children: [
IconButton(
icon: Icon(CupertinoIcons.back,color:Colors.white.withAlpha(170),size: 40,),
onPressed: (){
timer.cancel();
pageController.previousPage(duration: Duration(milliseconds: 800), curve: Curves.fastOutSlowIn);
}),
IconButton(
icon: Icon(CupertinoIcons.forward,color: Colors.white.withAlpha(150),size: 40,),
onPressed: () {
timer.cancel();
pageController.nextPage(duration: Duration(milliseconds: 800), curve: Curves.fastOutSlowIn);
}),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
],
),
),
// Cloud Biking index 1
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 700,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: CloudBikingContent(key: widget.key,)
),
// Stolen bicycles index 2
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.95
: 800,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: StolenBicyclesContent(key: widget.key),
),
// Scheduler index 3
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89 // Web
: 870,//MediaQuery.of(context).size.height * 0.90,//580, // Mobile
width: MediaQuery.of(context).size.width,
child: SchedulerContent(key: widget.key,),
),
// Orders index 4
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 850,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: OrdersContent(key: widget.key,),
),
// Bookings index 5
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 850,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: BookingsContent(key: widget.key),
),
NavigationBarBottom()
];
PageView 项:
List<Widget> slides = [
ScreenTypeLayout(
mobile: CloudBikingSlideMobile(
bgImage: mainBgImageMobile,
onTap: (){
controller.jumpTo(1);
// scrollController.jumpTo(index: 1);
// scrollController.scrollTo(index: 1, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);// .jumpTo(index: 1);
}),
desktop: CloudBikingSlideDesktop(
bgImage: mainBgImageDesktop,
onTap: (){
controller.jumpTo(1);
// scrollController.jumpTo(index: 1);
// scrollController.scrollTo(index: 1, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 1);
}),
),
ScreenTypeLayout(
mobile: StolenBicyclesSlideMobile(
bgImage: stolenBicyclesBgMobile,
onTap: (){
controller.jumpTo(2);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}),
desktop: StolenBicyclesSlideDesktop(
bgImage: stolenBicyclesBgDesktop,
onTap: (){
controller.jumpTo(2);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}),
),
ScreenTypeLayout(
mobile: SchedulerSlideMobile(
bgImage: schedulerBgImageMobile,
onTap: (){
controller.jumpTo(3);
// scrollController.jumpTo(index: 3);
// scrollController.scrollTo(index: 3, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 3);
}),
desktop: SchedulerSlideDesktop(
bgImage: schedulerBgImageDesktop,
onTap: (){
controller.jumpTo(3);
// scrollController.jumpTo(index: 3);
// scrollController.scrollTo(index: 3, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 3);
}),
),
ScreenTypeLayout(
mobile: OrdersSlideMobile(
bgImage: orderBgImageMobile,
onTap: (){
controller.jumpTo(4);
// scrollController.jumpTo(index: 4);
// scrollController.scrollTo(index: 4, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 4);
}),
desktop: OrdersSlideDesktop(
bgImage: orderBgImageDesktop,
onTap: (){
controller.jumpTo(4);
// scrollController.jumpTo(index: 4);
// scrollController.scrollTo(index: 4, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 4);
}),
),
ScreenTypeLayout(
mobile: BookingsSlideMobile(
bgImage: bookingBgImageMobile,
onTap: (){
controller.jumpTo(5);
// scrollController.jumpTo(index: 5);
// scrollController.scrollTo(index: 5, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 5);
}),
desktop: BookingsSlideDesktop(
bgImage: bookingBgImageDesktop,
onTap: (){
controller.jumpTo(5);
// scrollController.jumpTo(index: 5);
// scrollController.scrollTo(index: 5, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 5);
}),
),
];
列表视图:
Scaffold(
backgroundColor: Colors.transparent,
body: Container(
color: Colors.transparent,
child: Scrollbar(
controller: controller,
isAlwaysShown: true,
thickness: 10,
radius: Radius.circular(5),
// child: ScrollablePositionedList.builder(
// itemScrollController: scrollController,
// initialScrollIndex: 0,
// itemCount: homePageItems.length,
// itemBuilder: (BuildContext context, int index) => homePageItems[index],
child: ListView.builder(
controller: controller,
itemCount: homePageItems.length,
itemBuilder: (BuildContext context, int index) => homePageItems[index],
),
),
),
);
找到问题了。 ScrollController
的 jumpTo
期待一个像素值,而 ItemScrollController
的 jumpTo
期待一个索引跳转到并相应地移动.. 实际上是更好的解决方案恕我直言..
因此,通过将内容高度乘以其索引,您可以移动适量的像素..
double contentHeight = MediaQuery.of(context).size.height > 700 ? MediaQuery.of(context).size.height * 0.89 : MediaQuery.of(context).size.height * 0.85;
...
onTap: (){
controller.jumpTo(2 * contentHeight);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}
``
在我的应用程序中,我决定显示一个 ScrollBar
,因此 ScrollBar
和 ListView
都需要相同的 ScrollController
我不得不更改我的 ScrollablePositionedList.builder
到 ListView.builder
。
首先在我的 List<Widget> homePageItems
中是 PageView
(因此在索引 0 处),其中包含一些“幻灯片”,然后是其他小部件“内容”,它们是对幻灯片的解释。在每张幻灯片中都有一个按钮,它调用 controller.jumpTo();
以转到幻灯片的说明。
当我使用 ScrollablePositionedList.builder
时,scrollController.jumpTo(index: 5);
按预期工作,跳转到正确的“内容”,但使用 ListView.builder
它不会..它只是移动了几个像素,仅此而已..
有什么我现在设置错误或遗漏的 ListView.builder
?
ListView 项:
List<Widget> homePageItems = [
// carousell index 0
SizedBox(
height: MediaQuery.of(context).size.height > 700 ? MediaQuery.of(context).size.height * 0.89 : MediaQuery.of(context).size.height * 0.85,//580,
width: MediaQuery.of(context).size.width,
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Column(
children: [
Expanded(
child: PageView.builder(
controller: pageController,
onPageChanged: (index) {
timer.cancel();
setState(() {
if (index > _index) {
_current < slides.length -1 ? _current++ : _current = 0;
_index = index;
} else {
_current > 0 ? _current -- : _current = slides.length -1;
_index = index;
}
print('onPageChanged: index is : $index');
print('onPageChanged: _current is : $_current');
});
},
itemBuilder: (context, index){
return slides[_current];
}),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: slides.map((url) {
int index = slides.indexOf(url);
return Container(
width: 5.0,
height: 5.0,
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Colors.redAccent//Color.fromRGBO(0, 0, 0, 0.9)
: Colors.black54,//Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
],
),
Row(
children: [
IconButton(
icon: Icon(CupertinoIcons.back,color:Colors.white.withAlpha(170),size: 40,),
onPressed: (){
timer.cancel();
pageController.previousPage(duration: Duration(milliseconds: 800), curve: Curves.fastOutSlowIn);
}),
IconButton(
icon: Icon(CupertinoIcons.forward,color: Colors.white.withAlpha(150),size: 40,),
onPressed: () {
timer.cancel();
pageController.nextPage(duration: Duration(milliseconds: 800), curve: Curves.fastOutSlowIn);
}),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
],
),
),
// Cloud Biking index 1
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 700,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: CloudBikingContent(key: widget.key,)
),
// Stolen bicycles index 2
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.95
: 800,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: StolenBicyclesContent(key: widget.key),
),
// Scheduler index 3
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89 // Web
: 870,//MediaQuery.of(context).size.height * 0.90,//580, // Mobile
width: MediaQuery.of(context).size.width,
child: SchedulerContent(key: widget.key,),
),
// Orders index 4
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 850,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: OrdersContent(key: widget.key,),
),
// Bookings index 5
SizedBox(
height: MediaQuery.of(context).size.height > 700
? MediaQuery.of(context).size.height * 0.89
: 850,//MediaQuery.of(context).size.height * 0.90,//580,
width: MediaQuery.of(context).size.width,
child: BookingsContent(key: widget.key),
),
NavigationBarBottom()
];
PageView 项:
List<Widget> slides = [
ScreenTypeLayout(
mobile: CloudBikingSlideMobile(
bgImage: mainBgImageMobile,
onTap: (){
controller.jumpTo(1);
// scrollController.jumpTo(index: 1);
// scrollController.scrollTo(index: 1, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);// .jumpTo(index: 1);
}),
desktop: CloudBikingSlideDesktop(
bgImage: mainBgImageDesktop,
onTap: (){
controller.jumpTo(1);
// scrollController.jumpTo(index: 1);
// scrollController.scrollTo(index: 1, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 1);
}),
),
ScreenTypeLayout(
mobile: StolenBicyclesSlideMobile(
bgImage: stolenBicyclesBgMobile,
onTap: (){
controller.jumpTo(2);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}),
desktop: StolenBicyclesSlideDesktop(
bgImage: stolenBicyclesBgDesktop,
onTap: (){
controller.jumpTo(2);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}),
),
ScreenTypeLayout(
mobile: SchedulerSlideMobile(
bgImage: schedulerBgImageMobile,
onTap: (){
controller.jumpTo(3);
// scrollController.jumpTo(index: 3);
// scrollController.scrollTo(index: 3, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 3);
}),
desktop: SchedulerSlideDesktop(
bgImage: schedulerBgImageDesktop,
onTap: (){
controller.jumpTo(3);
// scrollController.jumpTo(index: 3);
// scrollController.scrollTo(index: 3, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 3);
}),
),
ScreenTypeLayout(
mobile: OrdersSlideMobile(
bgImage: orderBgImageMobile,
onTap: (){
controller.jumpTo(4);
// scrollController.jumpTo(index: 4);
// scrollController.scrollTo(index: 4, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 4);
}),
desktop: OrdersSlideDesktop(
bgImage: orderBgImageDesktop,
onTap: (){
controller.jumpTo(4);
// scrollController.jumpTo(index: 4);
// scrollController.scrollTo(index: 4, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 4);
}),
),
ScreenTypeLayout(
mobile: BookingsSlideMobile(
bgImage: bookingBgImageMobile,
onTap: (){
controller.jumpTo(5);
// scrollController.jumpTo(index: 5);
// scrollController.scrollTo(index: 5, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 5);
}),
desktop: BookingsSlideDesktop(
bgImage: bookingBgImageDesktop,
onTap: (){
controller.jumpTo(5);
// scrollController.jumpTo(index: 5);
// scrollController.scrollTo(index: 5, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 5);
}),
),
];
列表视图:
Scaffold(
backgroundColor: Colors.transparent,
body: Container(
color: Colors.transparent,
child: Scrollbar(
controller: controller,
isAlwaysShown: true,
thickness: 10,
radius: Radius.circular(5),
// child: ScrollablePositionedList.builder(
// itemScrollController: scrollController,
// initialScrollIndex: 0,
// itemCount: homePageItems.length,
// itemBuilder: (BuildContext context, int index) => homePageItems[index],
child: ListView.builder(
controller: controller,
itemCount: homePageItems.length,
itemBuilder: (BuildContext context, int index) => homePageItems[index],
),
),
),
);
找到问题了。 ScrollController
的 jumpTo
期待一个像素值,而 ItemScrollController
的 jumpTo
期待一个索引跳转到并相应地移动.. 实际上是更好的解决方案恕我直言..
因此,通过将内容高度乘以其索引,您可以移动适量的像素..
double contentHeight = MediaQuery.of(context).size.height > 700 ? MediaQuery.of(context).size.height * 0.89 : MediaQuery.of(context).size.height * 0.85;
...
onTap: (){
controller.jumpTo(2 * contentHeight);
// scrollController.jumpTo(index: 2);
// scrollController.scrollTo(index: 2, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);//.jumpTo(index: 2);
}
``