Search code examples
flutterdartscrollscrollview

Create similiar list scroll in flutter


Reference

Does anyone have any idea how I could do that in flutter? The space between item 32 - 31 is larger than that between 31 - 30 and the color in item 30, 29 is gray compared to 31 which is white. Same with the items at the bottom.

ScrollTile is a simple Center Widget that has as a child a Text.

I tried like that, but I got stuck, I'm at first in the flutter:

 return Stack(
      children: [
        Positioned(
          left: 0,
          right: 0,
          top: 0,
          bottom: 0,
          child: SizedBox(
            height: 60,
            width: 200,
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    width: 70,
                    height: 4,
                    decoration: const BoxDecoration(
                      color: kPrimary500,
                    ),
                  ),
                  const SizedBox(
                    height: 100,
                  ),
                  Container(
                    width: 70,
                    height: 4,
                    decoration: const BoxDecoration(
                      color: kPrimary500,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
        Container(
          padding: EdgeInsets.only(top: 40, bottom: 40),
          child: ListWheelScrollView.useDelegate(
            controller: FixedExtentScrollController(
              initialItem: 15,
            ),
            itemExtent: 50,
            perspective: 0.0000000001,
            diameterRatio: 1.6,
            physics: const FixedExtentScrollPhysics(),
            squeeze: 0.6,
            useMagnifier: true,
            magnification: 1.6,
            onSelectedItemChanged: (index) {
              setState(() {
                currentSelection = selection[index];
              });
            },
            childDelegate: ListWheelChildLoopingListDelegate(
              children: List<Widget>.generate(
                selection.length,
                (index) => ScrollTile(
                  selection: selection[index].toString(),
                  selectedColor: currentSelection == selection[index]
                      ? kPrimary500
                      : kWhite,
                ),
              ),
            ),
          ),
        ),
      ],
    );

Solution

  • You can refer to the below code:

    PageController con = PageController(
        viewportFraction: 0.2,
        initialPage: 5,
      );
      int currentValue = 5;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SizedBox(
              height: 400,
              width: 80,
              child: Stack(
                children: [
                  _surroundingBars(),
                  PageView(
                    physics: const BouncingScrollPhysics(),
                    controller: con,
                    scrollDirection: Axis.vertical,
                    onPageChanged: (index) => setState(() {
                      currentValue = index;
                    }),
                    children: [
                      ...List.generate(
                          100,
                          (index) {
                            return Center(
                                  child: Text(
                                index.toString(),
                                style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                    fontSize: currentValue == index
                                        ? 54
                                        : currentValue == index - 1 || currentValue == index + 1
                                            ? 36
                                            : 28,
                                    color: currentValue == index
                                        ? Colors.indigo
                                        : currentValue == index - 1 || currentValue == index + 1
                                            ? Colors.grey
                                            : Colors.grey.withOpacity(0.5)),
                              ));
                          })
                    ],
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
    
      Widget _surroundingBars(){
        return  Center(
          child: SizedBox(
            height: 100,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ...List.generate(
                    2,
                        (index) => const Divider(
                      thickness: 5,
                      color: Colors.indigo,
                    ))
              ],
            ),
          ),
        );
      }
    

    It's not the perfect way to do this, but will work for your use case.

    You can change the height and width from the SizedBox, if you want to edit spacing between the numbers you can increase/decrease the viewportFraction property of pageController(1.0 means max and 0.0 means min).

    and will look like this:

    enter image description here