flutter_material_pickers 1.2.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 87

Flutter Material Pickers #

A flutter package containing commonly used material design picker dialogs. Some are new, some wrap existing or built in pickers with a common dialog and access function.

It includes:

  • New Pickers
    • showMaterialScrollPicker:
      • Allows selection of a string via a slot machine carousel
    • showMaterialNumberPicker:
      • Allows selection of a number via a slot machine carousel
    • showMaterialRadioPicker:
      • Allows selection of a single from a radio list
    • showMaterialCheckboxPicker:
      • Allows selection of many values from a checkbox list
    • showMaterialSelectionPicker:
      • Allows selection of a single value via an icon label list
  • Convenience Pickers
    • showMaterialDatePicker:
      • Allows selection of a date (uses the core date picker)
    • showMaterialTimePicker:
      • Allows selection of a time (uses the core time picker)
    • showMaterialColorPicker:
      • Allows RGB selection of a color (uses the ColorPicker of flutter_colorpicker)
    • showMaterialPalettePicker:
      • Allows Material palette selection of a color (uses the MaterialPicker of flutter_colorpicker)
    • showMaterialSwatchPicker:
      • Allows selection of a color from swatches (uses the BlockPicker of flutter_colorpicker)
  • Dialog
    • showMaterialResponsiveDialog:
      • Extends Dialog by making it responsive to screen orientation changes

All helpers implement an onChange handler to return picked option(s).

Example Usage #

Empty Dialog Example #

Although not a picker, per se, the showMaterialEmptyPicker helper displays the universal material design dialog wrapper that the pickers appear in. Using this directly, however, allows any content to be injected into the content area by passing in a custon Widget as the child. This code shows the basic structure of all the helpers:

showMaterialResponsiveDialog(
    context: context,
    child: Center(
        child: Container(
            padding: EdgeInsets.all(30.0),
            child: Text("Any content here."),
            style: TextStyle(
                fontSize: 20.0,
                fontStyle: FontStyle.italic,
            ),
        ),
    ),
);

Scroll Picker Example #

var selectedUsState = "Connecticut";

List<String> usStates = <String>[
  'Alabama',
  'Alaska',
  'Arizona',
  'Arkansas',
  'California',
  'Colorado',
  'Connecticut',
  ...
];

showMaterialScrollPicker(
    context: context,
    title: "Pick Your City",
    items: usStates,
    selectedItem: selectedUsState,
    onChanged: (value) => setState(() => selectedUsState = value),
);

Number Picker Example #

var age = 25;

showMaterialNumberPicker(
  context: context,
  title: "Pick Your Age",
  maxNumber: 100,
  minNumber: 14,
  selectedNumber: age,
  onChanged: (value) => setState(() => age = value),
);

Checkbox Picker Example #

List<String> iceCreamToppings = <String>[
  'Hot Fudge',
  'Sprinkles',
  'Caramel',
  'Oreos',
  ...
];
List<String> selectedIceCreamToppings = <String>[
  'Hot Fudge',
  'Sprinkles',
];

showMaterialCheckboxPicker(
  context: context,
  title: "Pick Your Toppings",
  items: iceCreamToppings,
  selectedItems: selectedIceCreamToppings,
  onChanged: (value) => setState(() => selectedIceCreamToppings = value),
);

Radio Picker Example #

var selectedUsState = "Connecticut";

List<String> usStates = <String>[
  'Alabama',
  'Alaska',
  'Arizona',
  'Arkansas',
  'California',
  'Colorado',
  'Connecticut',
  ...
];

showMaterialRadioPicker(
  context: context,
  title: "Pick Your City",
  items: model.usStates,
  selectedItem: selectedUsState,
  onChanged: (value) => setState(() => selectedUsState = value),
);

Selection Picker Example #

String speed = 'Ludicrous';

List<String> speedOptions = <String>[
  'Light',
  'Ridiculous',
  'Ludicrous',
  'Plaid',
];

List<Icon> speedIcons = <Icon>[
  Icon(Icons.sort),
  Icon(Icons.clear_all),
  Icon(Icons.swap_calls),
  Icon(Icons.select_all),
];

showMaterialSelectionPicker(
  context: context,
  title: "Starship Speed",
  items: speedOptions,
  selectedItem: speed,
  icons: speedIcons,
  onChanged: (value) => setState(() => speed = value),
);

Time Picker Example #

var time = TimeOfDay.now();

showMaterialTimePicker(
  context: context,
  selectedTime: time,
  onChanged: (value) => setState(() => time = value),
);

Date Picker Example #

var date = DateTime.now();

showMaterialDatePicker(
  context: context,
  selectedDate: date,
  onChanged: (value) => setState(() => date = value),
);

Color Picker Example #

Color color = Colors.red;

showMaterialColorPicker(
  context: context,
  selectedColor: color,
  onChanged: (value) => setState(() => color = value),
);

Palette Picker Example #

Color palette = Colors.green;

showMaterialPalettePicker(
  context: context,
  selectedColor: palette,
  onChanged: (value) => setState(() => palette = value),
);

Swatch Picker Example #

Color swatch = Colors.blue;

showMaterialSwatchPicker(
  context: context,
  selectedColor: swatch,
  onChanged: (value) => setState(() => swatch = value),
);

Theming #

Note: it is highly recommended you use Flutter's theme method to style the dialogs across your entire application in one place. The example app demonstrates switching between light and dark themes globally. The elements that control dialog color are:

  • Theme.of(context).primaryColor controls the header background
  • Theme.of(context).backgroundColor controls the dialog background
  • Theme.of(context).textTheme.button.decorationColor controls the button text
  • Theme.of(context).primaryTextTheme.body1.color controls the header text

However, if for some reason you want to change colors in an individual dialog, several parameters are exposed to allow this:

showMaterialResponsiveDialog(
    context: context,
    headerColor: Colors.green, // background color of the header area
    backgroundColor: Colors.lightGreen, // background color of the entire dialog
    buttonTextColor: Colors.red, // text color of the action bar buttons
    child: Text("Custom dialog colors"),
);

Dependencies #

This widget set relies on these external third-party components:

Changelog #

Please see the Changelog page to know what's recently changed.

Authors #

Contributions #

If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.

If you fixed a bug or implemented a new feature, please send a pull request.

Releases #

[1.2.0] - 2/13/2020 #

  • Added headerTextColor parameter to each helper method

[1.1.0] - 2/13/2020 #

  • Added ability to control several colors to each show method

[1.0.0] - 2/13/2020 #

  • Initial Release

example/lib/main.dart

import 'package:dynamic_theme/dynamic_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_material_pickers/flutter_material_pickers.dart';
import 'package:intl/intl.dart';

import 'model.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DynamicTheme(
        defaultBrightness: Brightness.light,
        data: (brightness) => ThemeData(
              primarySwatch: Colors.indigo,
              brightness: brightness,
            ),
        themedWidgetBuilder: (context, theme) {
          return MaterialApp(
            title: 'Material Picker Examples',
            theme: theme,
            home: TestPage(),
          );
        });
  }
}

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  var model = ExampleModel();

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        backgroundColor: Theme.of(context).backgroundColor,
        appBar: AppBar(
          title: Text("Material Picker Examples"),
          actions: <Widget>[
            IconButton(
              icon: Theme.of(context).brightness == Brightness.dark
                  ? Icon(Icons.brightness_7)
                  : Icon(Icons.brightness_4),
              onPressed: () => DynamicTheme.of(context).setBrightness(
                  Theme.of(context).brightness == Brightness.dark
                      ? Brightness.light
                      : Brightness.dark),
            )
          ],
          bottom: TabBar(
            isScrollable: true,
            tabs: <Widget>[
              Tab(text: "New Pickers"),
              Tab(text: "Convenience Pickers"),
            ],
          ),
        ),
        body: SafeArea(
          child: Container(
            margin: EdgeInsets.all(8.0),
            child: TabBarView(
              children: <Widget>[
                Card(
                  child: Container(
                    padding: EdgeInsets.all(8.0),
                    child: ListView(
                      children: <Widget>[
                        buildEmptyRow(context),
                        Divider(),
                        buildScrollRow(context),
                        Divider(),
                        buildNumberRow(context),
                        Divider(),
                        buildCheckboxRow(context),
                        Divider(),
                        buildRadioRow(context),
                        Divider(),
                        buildSelectionRow(context),
                      ],
                    ),
                  ),
                ),
                Card(
                  child: Container(
                    padding: EdgeInsets.all(8.0),
                    child: ListView(
                      children: <Widget>[
                        buildTimeRow(context),
                        Divider(),
                        buildDateRow(context),
                        Divider(),
                        buildColorRow(context),
                        Divider(),
                        buildPaletteRow(context),
                        Divider(),
                        buildSwatchRow(context)
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Row buildEmptyRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Empty Dialog"),
            onPressed: () => showMaterialResponsiveDialog(
              context: context,
              child: Center(
                child: Container(
                  padding: EdgeInsets.all(30.0),
                  child: Text(
                    "This is the base dialog widget for the pickers. Unlike the off-the-shelf Dialog widget, it handles landscape orientations. You may place any content here you desire.",
                    style: TextStyle(
                      fontSize: 20.0,
                      fontStyle: FontStyle.italic,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
        Expanded(
          child: Text(
            "n/a",
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildScrollRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Scroll Picker"),
            onPressed: () => showMaterialScrollPicker(
              context: context,
              title: "Pick Your City",
              items: model.usStates,
              selectedItem: model.selectedUsState,
              onChanged: (value) =>
                  setState(() => model.selectedUsState = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            model.selectedUsState.toString(),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildNumberRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Number Picker"),
            onPressed: () => showMaterialNumberPicker(
              context: context,
              title: "Pick Your Age",
              maxNumber: 100,
              minNumber: 14,
              selectedNumber: model.age,
              onChanged: (value) => setState(() => model.age = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            model.age.toString(),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildCheckboxRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Checkbox Picker"),
            onPressed: () => showMaterialCheckboxPicker(
              context: context,
              title: "Pick Your Toppings",
              items: model.iceCreamToppings,
              selectedItems: model.selectedIceCreamToppings,
              onChanged: (value) =>
                  setState(() => model.selectedIceCreamToppings = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            model.selectedIceCreamToppings.toString(),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildRadioRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Radio Picker"),
            onPressed: () => showMaterialRadioPicker(
              context: context,
              title: "Pick Your City",
              items: model.usStates,
              selectedItem: model.selectedUsState,
              onChanged: (value) =>
                  setState(() => model.selectedUsState = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            model.selectedUsState.toString(),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildSelectionRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Selection Picker"),
            onPressed: () => showMaterialSelectionPicker(
              context: context,
              title: "Starship Speed",
              items: model.speedOptions,
              selectedItem: model.speed,
              icons: model.speedIcons,
              onChanged: (value) => setState(() => model.speed = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            model.speed,
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildTimeRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Time Picker"),
            onPressed: () => showMaterialTimePicker(
              context: context,
              selectedTime: model.time,
              onChanged: (value) => setState(() => model.time = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            MaterialLocalizations.of(context).formatTimeOfDay(model.time),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildDateRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Date Picker"),
            onPressed: () => showMaterialDatePicker(
              context: context,
              selectedDate: model.date,
              onChanged: (value) => setState(() => model.date = value),
            ),
          ),
        ),
        Expanded(
          child: Text(
            DateFormat.yMMMd().format(model.date),
            textAlign: TextAlign.right,
          ),
        ),
      ],
    );
  }

  Row buildColorRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Color Picker"),
            onPressed: () => showMaterialColorPicker(
              context: context,
              selectedColor: model.color,
              onChanged: (value) => setState(() => model.color = value),
            ),
          ),
        ),
        Expanded(child: Container()),
        Container(
          height: 20.0,
          width: 100.0,
          decoration: BoxDecoration(
            color: model.color,
          ),
        ),
      ],
    );
  }

  Row buildPaletteRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Palette Picker"),
            onPressed: () => showMaterialPalettePicker(
              context: context,
              selectedColor: model.palette,
              onChanged: (value) => setState(() => model.palette = value),
            ),
          ),
        ),
        Expanded(child: Container()),
        Container(
          height: 20.0,
          width: 100.0,
          decoration: BoxDecoration(
            color: model.palette,
          ),
        ),
      ],
    );
  }

  Row buildSwatchRow(BuildContext context) {
    return Row(
      children: <Widget>[
        Container(
          width: 150.0,
          child: RaisedButton(
            child: Text("Swatch Picker"),
            onPressed: () => showMaterialSwatchPicker(
              context: context,
              selectedColor: model.swatch,
              onChanged: (value) => setState(() => model.swatch = value),
            ),
          ),
        ),
        Expanded(child: Container()),
        Container(
          height: 20.0,
          width: 100.0,
          decoration: BoxDecoration(
            color: model.swatch,
          ),
        ),
      ],
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_material_pickers: ^1.2.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_material_pickers/flutter_material_pickers.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
80
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
85
Overall:
Weighted score of the above. [more]
87
Learn more about scoring.

We analyzed this package on Mar 27, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Maintenance issues and suggestions

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (flutter_colorpicker).

The description is too long. (-5 points)

Search engines display only the first part of the description. Try to keep the value of the description field in your package's pubspec.yaml file between 60 and 180 characters.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
flutter 0.0.0
flutter_colorpicker ^0.2.6 0.2.6 0.3.2
intl ^0.16.0 0.16.1
meta ^1.1.6 1.1.8
Transitive dependencies
collection 1.14.11 1.14.12
path 1.6.4
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test