-1

i am trying to implement like the below image.

enter image description here

I have a grid view which has 2 columns in which i am displaying my list.

enter image description here

As you can see in the above image it is showing 175/67 products.

my logic is i am giving my grid view a scroll controller.

I am adding a listener to that controller but i think my logic or calculation is wrong.

below is my code :

ScrollController _scrollController = new ScrollController();

in initstate i am giving adding a listener to scroll controller

_scrollController.addListener(_scrollListener);

void _scrollListener() {
    setState(() {
      debugPrint(_scrollController.offset.toString());
      debugPrint(count.toString());
      debugPrint(((_scrollController.offset / count).round()).toString());
      index = (_scrollController.offset / count).round();
      print(index);
    });
  }

the count is the total items in my list i.e 67.

as i scroll down it is giving wrong output.

please tell me where i am going wrong.

where my logic has gone wrong?

below is my grid view code:

DragSelectGridView(
                      shrinkWrap: true,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        childAspectRatio: (itemWidth / itemHeight),
                        crossAxisCount: 2,
                      ),
                      physics: ClampingScrollPhysics(),
                      gridController: gridController,
                      scrollController: _scrollController,
                      itemCount: items.length,
                      itemBuilder: (context, index, selected) {
                       
                        return ProductCard(
                          data: items[index],
                          isSelected: selected,
                        );
                      },
                    ),

Thanks in Advance!!!

Manish Shah
  • 17
  • 2
  • 8

3 Answers3

0

You can use the ScrollablePositionedList to get the index of current visible items. Check my example app here:

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

const numberOfItems = 500;
const randomMax = 1 << 32;

void main() {
  runApp(ScrollablePositionedListExample());
}

class ScrollablePositionedListExample extends StatelessWidget {
  const ScrollablePositionedListExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Example App',
      home: const SampleApp(),
    );
  }
}

class SampleApp extends StatefulWidget {
  const SampleApp({Key? key}) : super(key: key);

  @override
  _SampleAppState createState() => _SampleAppState();
}

class _SampleAppState extends State<SampleApp> {
  final ItemScrollController itemScrollController = ItemScrollController();
  final ItemPositionsListener itemPositionsListener =
      ItemPositionsListener.create();
  late List<Color> itemColors;

  @override
  void initState() {
    super.initState();
    final colorGenerator = Random(42490823);
    itemColors = List<Color>.generate(numberOfItems,
        (int _) => Color(colorGenerator.nextInt(randomMax)).withOpacity(1));
  }

  @override
  Widget build(BuildContext context) => Material(
        child: OrientationBuilder(
          builder: (context, orientation) => Column(
            children: <Widget>[
              Expanded(
                child: ScrollablePositionedList.builder(
                  itemCount: numberOfItems,
                  itemBuilder: (context, index) => item(
                    index,
                  ),
                  itemScrollController: itemScrollController,
                  itemPositionsListener: itemPositionsListener,
                  scrollDirection: Axis.vertical,
                ),
              ),
              positionsView,
            ],
          ),
        ),
      );

  Widget get positionsView => ValueListenableBuilder<Iterable<ItemPosition>>(
        valueListenable: itemPositionsListener.itemPositions,
        builder: (context, positions, child) {
          int? currentPosition;
          if (positions.isNotEmpty) {
            currentPosition = positions
                .where((ItemPosition position) => position.itemLeadingEdge < 1)
                .reduce((ItemPosition max, ItemPosition position) =>
                    position.itemLeadingEdge > max.itemLeadingEdge
                        ? position
                        : max)
                .index;
          }
          return Container(
              color: Colors.grey,
              padding: EdgeInsets.all(10),
              child: Text('${currentPosition ?? ''}/$numberOfItems}'));
        },
      );

  Widget item(int i) {
    return InkWell(
      // You can still click on the item here, for example put it in to the cart, etc
      onTap: () => Navigator.of(context).push(MaterialPageRoute(
          builder: (context) => Scaffold(
                appBar: AppBar(),
              ))),
      child: SizedBox(
        height: 150,
        child: Container(
          color: itemColors[i],
          child: Center(
            child: Text('Item $i'),
          ),
        ),
      ),
    );
  }
}
Bach
  • 2,928
  • 1
  • 6
  • 16
  • i thing why i have used drag select gridview is i am able to select some items from my list that is why i cant use scrollable positioned list, display in a gridview the requirement so that is why i have used that – Manish Shah Oct 12 '21 at 09:30
  • is there any way that i can use gridview in scrollable positioned list ?? – Manish Shah Oct 12 '21 at 09:32
  • @ManishShah It's gonna take a while as you need to calculate the exact index of the visible items. If I understand correctly, you need to be able to click on the item as well as scrolling down the list. In this case I've updated my answer below so that each child is an InkWell that might satisfy your requirement. – Bach Oct 12 '21 at 09:38
  • @ Bach no u didnt understand me correct i want the red circle from first image part logic in my list . the design i have created main is my logic is not working in girdview – Manish Shah Oct 12 '21 at 09:42
  • @ManishShah in my answer, that red circle is the `positionsView` widget. You can try running the app, scroll up/ down and see the item count updating. – Bach Oct 12 '21 at 09:44
  • @ManishShah my previous comment is just to explain to you that `ScrollablePositionedList` can behave like `drag select gridview` so no need to worry about being able to select some items as your first comment stated – Bach Oct 12 '21 at 09:46
  • yes i saw that your code is working i am asking how can i do the same in gridview ? – Manish Shah Oct 12 '21 at 09:47
  • ohh so how can i select some items in scrollable postioned list ?? – Manish Shah Oct 12 '21 at 09:48
  • i ran your code when i scroll down to the last element or last item in the list it is showing me 494 only. – Manish Shah Oct 12 '21 at 09:51
  • @ManishShah Just updated my answer, basically it now show the index of the last visible item on the screen – Bach Oct 12 '21 at 09:55
0

look at this code and see dose it useful or not

 NotificationListener<ScrollNotification>(
                                onNotification: (notification) {
                                  //get height of each item
                                  var height=notification.metrics.maxScrollExtent/items.length;
                                  //get position of item
                                  var position=((notification.metrics.maxScrollExtent-notification.metrics.extentAfter)/height).round();
                                  print('postion is $position and the lenght is ${_catcontroller.products.length}');
                                  return true;
                                },
Mj darvishi
  • 208
  • 1
  • 7
-1
GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemBuilder: (_, index) => FlutterLogo(),
  itemCount: 4,)