Open oha2004 opened 4 years ago
@oha2004 gesture detectors do get a bit 'janky' when conflicting scroll views are present, in this case a vertical scroll view from the SingleChildScrollView
and a horizontal scroll from the flutter_swiper
, but from what I noticed while trying to replicate this issue was that first off you need to have some sort of vertical bound for the swiper
to actually show up otherwise it throws an error. So conflicting scrolls would not be a problem if swiper
does not take up a good part of the screen. Even if it does, (as is the case with my source code below), the pull for the refresh as well as the swipe for the swiper is detected well. The 'jank' that I was assuming is almost negligible.
This one is highly unlikely but it is worth mentioning this, one very common mistake can also be that your Column
does not have enough children for it to be able to scroll, so I would suggest check that as well just to be sure.
Coming back to my first point, I tried to replicate your issue using the following source code, I would also suggest to share yours if you are unable to resolve this with the following insights.
body: LiquidPullToRefresh(
key: _refreshIndicatorKey,
onRefresh: _handleRefresh,
showChildOpacityTransition: false,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
width: double.maxFinite,
height: 500.0,
child: Swiper(
itemCount: 3,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 100.0,
height: 100.0,
color: Colors.red,
),
);
},
),
),
SizedBox(
height: 100.0,
),
Container(
width: double.maxFinite,
height: 200.0,
color: Colors.blue,
),
SizedBox(
height: 100.0,
),
Container(
width: double.maxFinite,
height: 200.0,
color: Colors.blue,
),
SizedBox(
height: 100.0,
),
Container(
width: double.maxFinite,
height: 200.0,
color: Colors.blue,
)
],
),
)),
The following output is received.
If you have any further questions feel free to ask. Again if this does not help in resolving the issue post the source code for me to replicate it exactly.
My code is very similar to yours
List<String> pics = [
'https://i0.wp.com/cdn-prod.medicalnewstoday.com/content/images/articles/326/326598/close-up-of-plate-of-food-being-passed-around-at-dinner-table.jpg?w=1155&h=1539',
'https://blog.nasm.org/hubfs/iStock-1162184637.jpg',
'https://blog.tefal.co.uk/wp-content/uploads/2017/08/25-reasons-home-cooked-is-always-best.jpg',
];
// Just some random pictures
.
.
.
body: LiquidPullToRefresh(
onRefresh: _refreshOn,
child: SingleChildScrollView(
child: Column(children: <Widget>[
Container(
height: 175,
child: Swiper(
itemCount: pics.length,
viewportFraction: 0.80,
pagination: new SwiperPagination(
builder: const DotSwiperPaginationBuilder(
size: 7,
activeSize: 10,
space: 7,
color: Colors.white60,
)),
scale: 0.85,
itemBuilder: (context, index) {
return InkWell(
onTap: () {},
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: pics.elementAt(index),
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
);
},
)),
SizedBox(
height: 20,
),
..... // Other widgets with enough height to scroll
]),
)
),
Pull to refresh somtimes is working with first element of Swiper but always not with others
I tried out your code and I noticed that immediately after scrolling the swiper
if you try to refresh it janks most of the time, whereas if you use the built in RefreshIndicator
there is no issue at all. If you wait and then try to refresh the package works as expected. It is strange however that in the source code I tried initially, even though very much the same, this was not the case. I don't think pagination part is the culprit since that does not explain anything. The immediate switching of swipe directions is probably the reason and there must be a way to optimize this. I'll get back to you when I can find a way to do the same.
I think I may have the same bug, as I can not pull to refresh only when my list is empty.
return LiquidPullToRefresh(
scrollController: scrollController,
showChildOpacityTransition: false,
onRefresh: viewModel.onRefreshAnimalAds,
child: ListView(
shrinkWrap: true,
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
),
child: Row(
children: <Widget>[
Expanded(
child: Text(viewModel.category.name.capitalize(),
style: Theme.of(context).textTheme.display2),
),
IconButton(
icon: Icon(
Icons.add,
color: Colors.grey.shade500,
),
onPressed: () => print('add'))
],
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 10, left: 20),
child: RoundedSquareButton(
size: 50,
borderRadius: 10,
isSelected: false,
child: Icon(
CustomIcons.filtra,
color: Theme.of(context).accentColor,
),
onTap: () => print('filtra')),
)
]..addAll(Category.values
.toList()
.map((category) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: CategoryButtonBuilder.fromCategory(
isSelected: viewModel.category == category,
category: category,
size: 50,
isCollapsed: true,
borderRadius: 10,
),
))
.toList()),
),
),
),
Divider(),
VerticalGrid(
widgetInjection: InfoCard(
title: 'Custom Card',
message:
'Check our last update! This new version (2.2v) comes with 3 new functionalities.',
),
ads: viewModel.animalAds,
),
],
),
);
}
}
When viewModel.animalAds are empty, it does not work, however when the list is not empty it works as expected. I tried to change to RefreshIndicator, and it works well with it in both cases.
In case you want to see the VerticalGrid widget:
child: StaggeredGridView.count(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
crossAxisSpacing: 20,
mainAxisSpacing: 20,
crossAxisCount: 2,
children: (widgetInjection == null ? [] : [widgetInjection])
..addAll(ads
.map((ad) => AnimalCard(
animalAd: ad as AnimalAd,
))
.toList()),
staggeredTiles: List.generate(
ads.length + 1, (int index) => StaggeredTile.fit(1))),
);```
Im using a slider from flutter_swiper in my app The pull function wont work and i cant pull down its stuck for maybe a conflict with
flutter_swiper