settings_item 2.0.0 copy "settings_item: ^2.0.0" to clipboard
settings_item: ^2.0.0 copied to clipboard

A beautiful, customizable expandable menu widget for Flutter settings pages with smooth animations and Material Design 3 styling. Supports switch, expandable, and button modes.

Settings Expandable Menu #

pub package License: MIT

A beautiful, customizable expandable menu widget for Flutter settings pages with smooth animations and Material Design 3 styling.

Demo

Features #

Three Operation Modes:

  • Switch Mode: Toggle switch for on/off settings
  • Expandable Mode: Expandable content with smooth animations and up arrow
  • Button Mode: Left arrow rotation without content expansion

🎨 Highly Customizable:

  • Custom prefix icons with themed containers
  • Custom title text with Material Design typography
  • Custom suffix widgets for advanced interactions
  • Custom expanded content widgets
  • Theme-aware colors and styling

Smooth Animations:

  • Butter-smooth expansion/collapse animations
  • Rotating arrow indicators with easing curves
  • Interactive bounce feedback with s_bounceable
  • Elegant toggle switches with s_toggle

🎯 Developer Friendly:

  • Simple, intuitive API
  • Two state management modes: Internal (automatic) or external (controlled)
  • Comprehensive documentation
  • Type-safe parameter configuration
  • Callback support for state changes and expansion events

Installation #

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

dependencies:
  settings_item: ^2.0.0

Then run:

flutter pub get

Usage #

State Management (External State) #

Example using external state management:

SettingsItem supports two state management modes:

  1. Internal State (Uncontrolled) - Widget manages its own state automatically
  2. External State (Controlled) - Parent widget controls the state

No need to manage state in your parent widget! Just set an optional initialState:

// Simple switch with internal state - no state variable needed!
SettingsItem(
  parameters: ExpandableParameters(
    prefixIcon: Icons.notifications_rounded,
    title: 'Notifications',
    isSwitch: true,
  ),
  initialState: true,  // Optional: defaults to false
  onChange: (value) {
    // Optional: listen to state changes
    print('Notifications: $value');
  },
)

External State Management (Controlled Mode)

Full control over state for complex scenarios:

class MySettingsPage extends StatefulWidget {
  @override
  State<MySettingsPage> createState() => _MySettingsPageState();
}

class _MySettingsPageState extends State<MySettingsPage> {
  bool notificationsEnabled = true;

  @override
  Widget build(BuildContext context) {
    return SettingsItem(
      parameters: ExpandableParameters(
        prefixIcon: Icons.notifications_rounded,
        title: 'Notifications',
        isSwitch: true,
      ),
      isActive: notificationsEnabled,  // Provide external state
      onChange: (value) {
        setState(() {
          notificationsEnabled = value;
        });
      },
    );
  }
}

Basic Example - Switch Mode #

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

class MySettingsPage extends StatefulWidget {
  @override
  State<MySettingsPage> createState() => _MySettingsPageState();
}

class _MySettingsPageState extends State<MySettingsPage> {
  bool notificationsEnabled = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Settings')),
      body: ListView(
        padding: EdgeInsets.all(16),
        children: [
          SettingsExpendableMenu(
            parameters: ExpandableParameters(
              prefixIcon: Icons.notifications_rounded,
              title: 'Notifications',
              isSwitch: true,
            ),
            isActive: notificationsEnabled,
            onChange: (value) {
              setState(() {
                notificationsEnabled = value;
              });
            },
          ),
        ],
      ),
    );
  }
}
```Internal State

Simplest expandable menu - no state management needed:

```dart
SettingsItem(
  parameters: ExpandableParameters(
    prefixIcon: Icons.settings_rounded,
    title: 'Display Settings',
    isExpandeable: true,
    expandedWidget: Column(
      children: [
        ListTile(
          leading: Icon(Icons.brightness_6),
          title: Text('Brightness'),
          onTap: () {
            // Handle brightness
          },
        ),
        ListTile(
          leading: Icon(Icons.text_fields),
          title: Text('Font Size'),
          onTap: () {
            // Handle font size
          },
        ),
      ],
    ),
  ),
  // No isActive needed - widget manages its own state!
)

Expandable Mode with Content (External State) #

Expandable Mode with Content #

bool accountExpanded = false;

SettingsExpendableMenu(
  parameters: ExpandableParameters(
    prefixIcon: Icons.account_circle_rounded,
    title: 'Account Settings',
    isExpandeable: true,
    expandedWidget: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        ListTile(
          leading: Icon(Icons.person),
          title: Text('Edit Profile'),
          onTap: () {
            // Handle profile edit
          },
        ),
        ListTile(
          leading: Icon(Icons.lock),
          title: Text('Change Password'),
          onTap: () {
            // Handle password change
          },
        ),
        ListTile(
          leading: Icon(Icons.logout),
          title: Text('Sign Out'),
          onTap: () {
            // Handle sign out
          },
        ),
      ],
    ),
  ),
  isActive: accountExpanded,
  onChange: (value) {
    setState(() {
      accountExpanded = value;
    });
  },
)

Button Mode (No Expansion) #

bool themeButtonActive = false;

SettingsExpendableMenu(
  parameters: ExpandableParameters(
    prefixIcon: Icons.palette_rounded,
    title: 'Theme Settings',
    isExpandeable: false, // Only rotates arrow, doesn't expand
  ),
  isActive: themeButtonActive,
  onChange: (value) {
    setState(() {
      themeButtonActive = value;
    });
    // Navigate to theme settings page
    Navigator.push(context, MaterialPageRoute(
      builder: (_) => ThemeSettingsPage(),
    ));
  },
)

Advanced Example - Custom Suffix Widget #

bool privacyExpanded = false;
int privacyLevel = 2;

SettingsExpendableMenu(
  parameters: ExpandableParameters(
    prefixIcon: Icons.security_rounded,
    title: 'Privacy Level',
    isExpandeable: true,
    suffixWidget: Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: BoxDecoration(
        color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.1),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        ['Low', 'Medium', 'High'][privacyLevel],
        style: TextStyle(
          color: Theme.of(context).colorScheme.primary,
          fontWeight: FontWeight.w600,
        ),
      ),
    ),
    expandedWidget: Column(
      children: [
        RadioListTile(
          title: Text('Low'),
          value: 0,
          groupValue: privacyLevel,
          onChanged: (value) {
            setState(() {
              privacyLevel = value!;
            });
          },
        ),
        RadioListTile(
          title: Text('Medium'),
          value: 1,
          groupValue: privacyLevel,
          onChanged: (value) {
            setState(() {
              privacyLevel = value!;
            });?` | Current active/expanded state (optional - if null, uses internal state) |
| `initialState` | `bool` | Initial state when using internal state management (defaults to `false`)
          },
        ),
        RadioListTile(
          title: Text('High'),
          value: 2,
          groupValue: privacyLevel,
          onChanged: (value) {
            setState(() {
              privacyLevel = value!;
            });
          },
        ),
      ],
    ),
    onExpandedSectionToggle: () {
      print('Privacy section toggled!');
    },
  ),
  isActive: privacyExpanded,
  onChange: (value) {
    setState(() {
      privacyExpanded = value;
    });
  },
)

Parameters #

SettingsExpendableMenu #

Parameter Type Description
parameters ExpandableParameters Configuration for the menu item
isActive bool Current active/expanded state
onChange Function(bool)? Callback when state changes

ExpandableParameters #

Parameter Type Default Description
prefixIcon IconData? null Icon displayed on the left
title String? "Settings Item" Title text of the menu item
isSwitch bool false Shows toggle switch when true
isExpandeable bool true Enables content expansion when true
expandedWidget Widget? null Content shown when expanded
suffixWidget Widget? null Custom widget on the right (overrides default arrow/switch)
onExpandedSectionToggle VoidCallback? null Called when expansion state changes

Dependencies #

This package uses the following dependencies:

  • s_bounceable ^2.0.0 - For interactive bounce feedback
  • s_toggle ^2.0.1 - For elegant toggle switches

Example App #

A complete example app demonstrating all features is available in the example folder. Run it with:

cd example
flutter run

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Author #

SoundSliced

Changelog #

See CHANGELOG.md for a list of changes.

0
likes
160
points
126
downloads

Publisher

unverified uploader

Weekly Downloads

A beautiful, customizable expandable menu widget for Flutter settings pages with smooth animations and Material Design 3 styling. Supports switch, expandable, and button modes.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, s_packages

More

Packages that depend on settings_item