Search code examples
flutterlayoutpicker

Styling of Cupertino Picker in Flutter


I have tried to implement a layout like this using flutter. The desired layout

I have used the Cupertino Picker Class for that. But it just looks not as good as I want it to look. My actual layout

I have tried to fix it by using the properties, that are listed on the flutter website, but I did not find any better solution. How can I fix this issue or is there even another widget that is better in this case?

My code looks like this:

Widget build(BuildContext context) {
return CupertinoPageScaffold(
    navigationBar: CupertinoNavigationBar(
      backgroundColor: Colors.red,
    ),
    child: Container(
      child: Center(
        child: CupertinoPicker(
      itemExtent: 40,
      diameterRatio: 5,
      offAxisFraction: 10,
      backgroundColor: Colors.black54,
      onSelectedItemChanged: (int index) {
        print(index);
      },
      children: <Widget>[
        Text('Tap', style: TextStyle(color:Colors.white)),
        Text('Colorbattle',style: TextStyle(color:Colors.white)),
        Text('Patience',style: TextStyle(color:Colors.white)),
      ],
    ))));

} }


Solution

  • Playing around your code, I've tried to implement the same behavior. I've observed that changing the values of diameterRatio and offAxisFraction could change the way your UI look like. In my sample, the values of diameterRatio and offAxisFraction is 10 and -1 respectively. Just imagine this kind of roulette:

    enter image description here

    diameterRatio is the diameter of the cylinder and offAxisFraction is the axis where the side of the cylinder is facing. To mimic the example in the picture, set the value of the offAxisFraction to a positive value, in the implementation shown below, I've set it to 10.

    enter image description here

    Below is an example of copy the behavior of the UI you're trying to replicate:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(
            backgroundColor: Colors.red,
          ),
          child: Center(
            child: Container(
              // color: Colors.black54,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.white),
                borderRadius: BorderRadius.all(
                  Radius.circular(15),
                ),
              ),
              width: 200.0,
              height: 150.0,
              child: Center(
                child: CupertinoPicker(
                  itemExtent: 40,
                  diameterRatio: 10,
                  offAxisFraction: -1,
                  backgroundColor: Colors.black54,
                  onSelectedItemChanged: (int index) {
                    print(index);
                  },
                  children: <Widget>[
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(right: 40.0),
                        child: Text(
                          'Estimate',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(right: 40.0),
                        child: Text(
                          'Random',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(right: 40.0),
                        child: Text(
                          'Colorbattle',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(right: 40.0),
                        child: Text(
                          'Patience',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(right: 40.0),
                        child: Text(
                          'Tap',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    

    Output:

    enter image description here