How to create a roller like animation? Similar to slot machine

Viewed 509

I want to create a custom animation, basically something like a slot machine, but I want the user to be able to move up/down each block with letters by his finger, not spin automatically. I tried looking into this library: https://pub.dev/packages/roll_slot_machine/example but doesn't seem to fit my needs. Can I get any hints how to approach this?

What I am trying to achieve:

enter image description here

1 Answers

Using CupertinoPicker can archive similar like this. You can use Stack for background selection, Container's decoration to improve view.

Run on dartPad

enter image description here

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

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

class _CustomRollStateMachineState extends State<CustomRollStateMachine> {
  int aCode = 'A'.codeUnitAt(0);
  int zCode = 'Z'.codeUnitAt(0);

  late List<String> alphabets = List<String>.generate(
    zCode - aCode + 1,
    (index) => String.fromCharCode(aCode + index),
  );

  List<String?> result = List.filled(4, null);
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 124,
          child: Row(
            children: [
              Expanded(
                child: RollerSlot(
                  callback: (p0) {
                    setState(() {
                      result[0] = p0;
                    });
                  },
                  data: alphabets,
                ),
              ),
              Expanded(
                child: RollerSlot(
                  callback: (p0) {
                    setState(() {
                      result[1] = p0;
                    });
                  },
                  data: alphabets,
                ),
              ),
              Expanded(
                child: RollerSlot(
                  callback: (p0) {
                    setState(() {
                      result[2] = p0;
                    });
                  },
                  data: alphabets,
                ),
              ),
              Expanded(
                child: RollerSlot(
                  callback: (p0) {
                    setState(() {
                      result[3] = p0;
                    });
                  },
                  data: alphabets,
                ),
              ),
            ],
          ),
        ),
        Text("Result: ${result.join()}")
      ],
    );
  }
}


class RollerSlot extends StatelessWidget {
  const RollerSlot({
    Key? key,
    required this.data,
    required this.callback,
  }) : super(key: key);

  final List<String> data;
  final Function(String) callback;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.black,
        ),
      ),
      child: CupertinoPicker(
          itemExtent: 24.0,
          onSelectedItemChanged: (value) => callback(data[value]),
          children: data
              .map(
                (e) => Text(e),
              )
              .toList()),
    );
  }
}
Related