card_settings_ui 1.2.0 copy "card_settings_ui: ^1.2.0" to clipboard
card_settings_ui: ^1.2.0 copied to clipboard

A card based settings ui for flutter.

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
            seedColor: Color(0xff6750a4), brightness: Brightness.light),
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
            seedColor: Color(0xff6750a4), brightness: Brightness.dark),
      ),
      debugShowCheckedModeBanner: false,
      home: const SettingsPage(),
    );
  }
}

class SettingsPage extends StatefulWidget {
  const SettingsPage({super.key});

  @override
  State<SettingsPage> createState() => _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  bool isEnabled = true;
  bool? selectAll = false;
  List<bool?> securityItem = [false, false, false];

  void updateSelectAll() {
    if (securityItem.every((item) => item == true)) {
      selectAll = true;
    } else if (securityItem.every((item) => item == false)) {
      selectAll = false;
    } else {
      selectAll = null;
    }
  }

  double size = 10.0;
  String density = densityList[0];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Settings'),
      ),
      body: SettingsList(
        maxWidth: 800,
        sections: [
          SettingsSection(
            title: Text('Email density'),
            tiles: densityList
                .map((e) => SettingsTile<String>.radioTile(
                      title: Text(e),
                      radioValue: e,
                      groupValue: density,
                      onChanged: (String? value) {
                        if (value != null) {
                          setState(() {
                            density = value;
                          });
                        }
                      },
                    ))
                .toList(),
          ),
          SettingsSection(
            title: Text('Security'),
            tiles: <SettingsTile>[
              SettingsTile.navigation(
                onPressed: (_) =>
                    showToast(context, 'Click checkbox in front to select all'),
                leading: Checkbox(
                  value: selectAll,
                  onChanged: (_) {
                    if (selectAll == null || selectAll == true) {
                      selectAll = false;
                      securityItem.fillRange(0, securityItem.length, false);
                    } else {
                      selectAll = true;
                      securityItem.fillRange(0, securityItem.length, true);
                    }
                    setState(() {});
                  },
                  tristate: true,
                ),
                title: Text('Select all'),
              ),
            ],
          ),
          SettingsSection(
            tiles: <SettingsTile>[
              SettingsTile.checkboxTile(
                onToggle: (value) {
                  securityItem[0] = value ?? !securityItem[0]!;
                  updateSelectAll();
                  setState(() {});
                },
                initialValue: securityItem[0],
                leading: Icon(Icons.dialpad),
                title: Text('PIN'),
                description: Text('Allow user log in with PIN'),
              ),
              SettingsTile.checkboxTile(
                onToggle: (value) {
                  securityItem[1] = value ?? !securityItem[1]!;
                  updateSelectAll();
                  setState(() {});
                },
                initialValue: securityItem[1],
                leading: Icon(Icons.password_rounded),
                title: Text('Password'),
                description: Text('Allow user log in with password'),
              ),
              SettingsTile.checkboxTile(
                onToggle: (value) {
                  securityItem[2] = value ?? !securityItem[2]!;
                  updateSelectAll();
                  setState(() {});
                },
                initialValue: securityItem[2],
                leading: Icon(Icons.fingerprint),
                title: Text('Fingerprint'),
                description: Text('Allow user log in with fingerprint'),
              ),
            ],
          ),
          SettingsSection(
            title: Text('Subtitle'),
            tiles: <SettingsTile>[
              SettingsTile.switchTile(
                onToggle: (value) {
                  isEnabled = value ?? !isEnabled;
                  setState(() {});
                },
                initialValue: isEnabled,
                leading: Icon(Icons.subtitles),
                title: Text('Enable subtitle'),
              ),
              SettingsTile.navigation(
                onPressed: (_) => subtitleSizeDialog(context),
                enabled: isEnabled,
                leading: Icon(Icons.format_size),
                title: Text('Subtitle size'),
                value: Text('$size'),
              ),
            ],
          ),
          SettingsSection(
            bottomInfo: Text('Upload settings to cloud'),
            tiles: <SettingsTile>[
              SettingsTile(
                onPressed: (_) => showToast(context, 'Upload successfully'),
                title: Text('Upload'),
                trailing: Icon(Icons.cloud_upload_rounded),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Future subtitleSizeDialog(BuildContext context) {
    return showDialog(
      builder: (context) {
        return AlertDialog(
          title: const Text('Subtitle font size'),
          content: StatefulBuilder(builder: (BuildContext context, _) {
            return Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                for (final double i in subtitleSize) ...<Widget>[
                  if (i == size) ...<Widget>[
                    FilledButton(
                      onPressed: () async {
                        setState(() {
                          size = i;
                        });
                        Navigator.of(context).pop();
                      },
                      child: Text(i.toString()),
                    ),
                  ] else ...[
                    FilledButton.tonal(
                      onPressed: () async {
                        setState(() {
                          size = i;
                        });
                        Navigator.of(context).pop();
                      },
                      child: Text(i.toString()),
                    ),
                  ]
                ]
              ],
            );
          }),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Text(
                'Cancel',
                style: TextStyle(color: Theme.of(context).colorScheme.outline),
              ),
            ),
          ],
        );
      },
      context: context,
    );
  }

  void showToast(BuildContext context, String message) {
    ScaffoldMessenger.of(context)
      ..removeCurrentSnackBar()
      ..showSnackBar(
        SnackBar(
          content: Text(message),
        ),
      );
  }
}

final List<double> subtitleSize = [
  10.0,
  11.0,
  12.0,
  13.0,
  14.0,
  15.0,
];

const List<String> densityList = [
  'Default',
  'Comfortable',
  'Compact',
];
23
likes
140
points
441
downloads

Publisher

unverified uploader

Weekly Downloads

A card based settings ui for flutter.

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter

More

Packages that depend on card_settings_ui