Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't pull to refresh when using flutter_swiper package #49

Open
oha2004 opened this issue Jun 21, 2020 · 4 comments
Open

Can't pull to refresh when using flutter_swiper package #49

oha2004 opened this issue Jun 21, 2020 · 4 comments
Labels
bug Something isn't working

Comments

@oha2004
Copy link

oha2004 commented Jun 21, 2020

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

LiquidPullToRefresh.
-> SingleChildScrollView
--> Column
---> Swiper (flutter_swiper package)
---> Other widgets ...

@AadumKhor
Copy link
Collaborator

@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.

lqtr_swiper

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.

@oha2004
Copy link
Author

oha2004 commented Jun 26, 2020

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

@AadumKhor
Copy link
Collaborator

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.

@AadumKhor AadumKhor added the bug Something isn't working label Jun 26, 2020
@raulmabe
Copy link

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))),
    );```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants