How to make ListWheelScrollView horizontal
Asked Answered
R

7

20

I Am trying to have a horizontal ListView Widget that magnifies the center items. I tried using the normal ListView but I couldn't get the center items to magnify. Then while searching the flutter docs I came across ListWheelScrollView but unfortunately, it doesn't seem to support horizontal children layout. So basically am looking to create a horizontal ListView with center items magnification. I'd appreciate it if anyone can at least point me in the right direction. Thanks

Roane answered 30/9, 2018 at 14:1 Comment(0)
P
17

Edit: I have published package based on this.

pub.dev/packages/list_wheel_scroll_view_x

Here's my workaround.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class ListWheelScrollViewX extends StatelessWidget {
  final Widget Function(BuildContext, int) builder;
  final Axis scrollDirection;
  final FixedExtentScrollController controller;
  final double itemExtent;
  final double diameterRatio;
  final void Function(int) onSelectedItemChanged;
  const ListWheelScrollViewX({
    Key key,
    @required this.builder,
    @required this.itemExtent,
    this.controller,
    this.onSelectedItemChanged,
    this.scrollDirection = Axis.vertical,
    this.diameterRatio = 100000,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return RotatedBox(
      quarterTurns: scrollDirection == Axis.horizontal ? 3 : 0,
      child: ListWheelScrollView.useDelegate(
        onSelectedItemChanged: onSelectedItemChanged,
        controller: controller,
        itemExtent: itemExtent,
        diameterRatio: diameterRatio,
        physics: FixedExtentScrollPhysics(),
        childDelegate: ListWheelChildBuilderDelegate(
          builder: (context, index) {
            return RotatedBox(
              quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0,
              child: builder(context, index),
            );
          },
        ),
      ),
    );
  }
}
Perpetuity answered 11/9, 2019 at 3:20 Comment(3)
I am looking for something similar and wondered if you have an example implementing your code above?Picard
@Picard You use it as you would use ListWheelScrollView widget. But I have added scrollDirection which you can set to Axis.horizontalPerpetuity
BTW I have pushed it to package pub.dev/packages/list_wheel_scroll_view_xPerpetuity
S
13

This is not really a solution but a naive hack, You can do this using the built-in ListWheelScrollView by pairing it with the RotatedBox.

RotatedBox(
  quarterTurns: -1,
  child: ListWheelScrollView(
    controller: _scrollController,
    itemExtent: itemWidth,
    onSelectedItemChanged: (newIndex) {
      setState(() {
        selectedIndex = newIndex;
      });
    },
    children: List.generate(
      itemCount,
      (index) => RotatedBox(
        quarterTurns: 1,
        child: AnimatedContainer(
          duration: Duration(milliseconds: 400),
          width: index == selectedIndex ? 60 : 50,
          height: index == selectedIndex ? 60 : 50,
          alignment: Alignment.center,
          decoration: BoxDecoration(
            color: index == selectedIndex ? Colors.red : Colors.grey,
            shape: BoxShape.circle,
          ),
          child: Text('$index'),
        ),
      ),
    ),
  ),
);

Full source Code here

I recommend using this approach until this issue is resolved

Heres the output

enter image description here

Sublimity answered 22/3, 2021 at 4:56 Comment(1)
But to scroll this listview you need to scroll the mouse in y axis , how to make it more sensible by making it scroll when the mouse is scrolled in x axisRumen
L
3

copy this code and used it

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class ListWheelScrollViewX extends StatelessWidget {
  final Axis scrollDirection;
  final List<Widget>? children;
  final ScrollController? controller;
  final ScrollPhysics? physics;
  final double diameterRatio;
  final double perspective;
  final double offAxisFraction;
  final bool useMagnifier;
  final double magnification;
  final double overAndUnderCenterOpacity;
  final double itemExtent;
  final double squeeze;
  final ValueChanged<int>? onSelectedItemChanged;
  final bool renderChildrenOutsideViewport;
  final ListWheelChildDelegate? childDelegate;
  final Clip clipBehavior;

  const ListWheelScrollViewX({
    Key? key,
    this.scrollDirection = Axis.vertical,
    this.controller,
    this.physics,
    this.diameterRatio = RenderListWheelViewport.defaultDiameterRatio,
    this.perspective = RenderListWheelViewport.defaultPerspective,
    this.offAxisFraction = 0.0,
    this.useMagnifier = false,
    this.magnification = 1.0,
    this.overAndUnderCenterOpacity = 1.0,
    required this.itemExtent,
    this.squeeze = 1.0,
    this.onSelectedItemChanged,
    this.renderChildrenOutsideViewport = false,
    this.clipBehavior = Clip.hardEdge,
    required this.children,
  })  : childDelegate = null,
        super(key: key);

  const ListWheelScrollViewX.useDelegate({
    Key? key,
    this.scrollDirection = Axis.vertical,
    this.controller,
    this.physics,
    this.diameterRatio = RenderListWheelViewport.defaultDiameterRatio,
    this.perspective = RenderListWheelViewport.defaultPerspective,
    this.offAxisFraction = 0.0,
    this.useMagnifier = false,
    this.magnification = 1.0,
    this.overAndUnderCenterOpacity = 1.0,
    required this.itemExtent,
    this.squeeze = 1.0,
    this.onSelectedItemChanged,
    this.renderChildrenOutsideViewport = false,
    this.clipBehavior = Clip.hardEdge,
    required this.childDelegate,
  })  : children = null,
        super(key: key);

  @override
  Widget build(BuildContext context) {
    final _childDelegate = children != null
        ? ListWheelChildListDelegate(
            children: children!.map((child) {
            return RotatedBox(
              quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0,
              child: child,
            );
          }).toList())
        : ListWheelChildBuilderDelegate(
            builder: (context, index) {
              return RotatedBox(
                quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0,
                child: childDelegate!.build(context, index),
              );
            },
          );

    return RotatedBox(
      quarterTurns: scrollDirection == Axis.horizontal ? 3 : 0,
      child: ListWheelScrollView.useDelegate(
        controller: controller,
        physics: FixedExtentScrollPhysics(),
        diameterRatio: diameterRatio,
        perspective: perspective,
        offAxisFraction: offAxisFraction,
        useMagnifier: useMagnifier,
        magnification: magnification,
        overAndUnderCenterOpacity: overAndUnderCenterOpacity,
        itemExtent: itemExtent,
        squeeze: squeeze,
        onSelectedItemChanged: onSelectedItemChanged,
        renderChildrenOutsideViewport: renderChildrenOutsideViewport,
        clipBehavior: clipBehavior,
        childDelegate: _childDelegate,
      ),
    );
  }
}

Example

ListWheelScrollViewX(
    scrollDirection: Axis.horizontal,
    itemExtent: 120,
    children:...
),

Reference list_wheel_scroll_view_x

changes: convert to null safety

Leslileslie answered 22/10, 2021 at 20:28 Comment(0)
R
1

You can use this flutter package https://pub.dev/packages/carousel_slider. It also has a very helpful description and few samples to see how it looks. And it's compatible with dart 2.0 too.

Revolution answered 30/9, 2018 at 17:26 Comment(2)
pub.dartlang.org/packages/carousel, this package is dart 2.0 incompatible :(Concur
@Concur I have updated my answer now. Please take a look again.Revolution
C
1

You can make this work with the help of ListView and PageView along with NotificationListener. Below is my code for the same-

import 'dart:math';
import 'package:flutter/material.dart';        
const SCALE_FRACTION = 0.9;
        const FULL_SCALE = 1.0;
        final PAGER_HEIGHT = SizeConfig.screenHeight*0.32;
        const PAGER_WIDTH = double.infinity;

        class PaymentWidget extends StatefulWidget {
          @override
          State<StatefulWidget> createState() => _PaymentState();
        }

        class _PaymentState extends State<PaymentWidget> {
          double viewPortFraction = 0.9;
          int currentPage = 1;
          double page = 2.0;

          PageController pageController;

          final List<String> _cardsImages = ['image/path1', 'image/path2',
            'image/path3', 'image/path4'];

          @override
          void initState() {
            pageController = PageController(
                initialPage: currentPage, viewportFraction: viewPortFraction);
            super.initState();
          }

          @override
          Widget build(BuildContext context) {
            return Scaffold(
              appBar: null,
              body: _creditCardsList()
        );
        }

       Widget _creditCardsList() {
            return ListView(
              shrinkWrap: true,
                  children: <Widget>[
                    Container(
                      height: PAGER_HEIGHT,
                      child: NotificationListener<ScrollNotification>(
                        onNotification: (ScrollNotification notification) {
                          if (notification is ScrollUpdateNotification) {
                            setState(() {
                              page = pageController.page;
                            });
                          }
                        },
                        child: PageView.builder(
                          onPageChanged: (pos) {
                            setState(() {
                              currentPage = pos;
                            });
                          },
                          physics: BouncingScrollPhysics(),
                          controller: pageController,
                          itemCount: _cardsImages.length,
                          itemBuilder: (context, index) {
                            final scale =
                            max(SCALE_FRACTION, (FULL_SCALE - (index - page).abs()) + viewPortFraction);
                            return CreditCardTile(
                                _cardsImages[index], scale);
                          },
                        ),
                      ),
                    ),
                  ],
            );

          }

        Widget CreditCardTile(String image, double scale) {
            return Align(
              alignment: Alignment.bottomCenter,
              child:Container(
                  height: PAGER_HEIGHT * scale,
                  width: PAGER_WIDTH * scale,
                  child: Card(
                    elevation: 5,
                    shadowColor: constColors.blueWhiteShade,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10.0)
                    ),
                    clipBehavior: Clip.antiAlias,
                    child: Image.asset(
                      image,
                      fit: BoxFit.cover,
                    ),
                  )
              ) ,
            );

          }
Concur answered 14/5, 2020 at 12:8 Comment(0)
J
1
Transform.rotate(
  angle: -math.pi / 2,
  child: ListWheelScrollView()
}

use Transform.rotate

Jugendstil answered 15/3, 2021 at 2:28 Comment(0)
Y
1

Add 2 RotatedBox as Follows

 StreamBuilder<DocumentSnapshot>(
                    stream: FirebaseFirestore.instance
                        .collection('Categories')
                        .doc('EcomCat')
                        .snapshots(),
                    builder: (BuildContext context,
                        AsyncSnapshot<DocumentSnapshot> snapshot) {
                      if (snapshot.data == null) {
                        return Center(
                          child: CircularProgressIndicator(),
                        );
                      }

                      final DocumentSnapshot document = snapshot.data!;

                      final Map<String, dynamic> documentData =
                      document.data() as Map<String, dynamic>;
                     final List Category = documentData['category'];
                      return RotatedBox(quarterTurns: 1,
                        child: ListWheelScrollView.useDelegate(magnification: 200,
                            itemExtent: 180,
                            childDelegate: ListWheelChildBuilderDelegate(
                            childCount: Category.length,
                            builder: (context,index){
                            return Row(
                              children: [
                                RotatedBox(quarterTurns: -1,
                                  child: ElevatedButton(
                                    style: ElevatedButton.styleFrom(
                                        padding: EdgeInsets.all(10),
                                        shadowColor: Colors.black,
                                        primary: Colors.teal,
                                        shape: RoundedRectangleBorder(
                                            borderRadius:
                                            BorderRadius.circular(18))),
                                    onPressed: () {
                                      setState(() {
                                        categoryVal =
                                            Category[index].toString();
                                      });
                                    },
                                    child: Text(
                                      Category[index].toString(),
                                      style: themeData.textTheme.headline4,
                                    ),
                                  ),
                                ),
                              ],
                            );
                          },
                        )),
                      );
                    },
                  ),
Yurikoyursa answered 28/7, 2022 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.