Skip to content

Reusable custom multi-select choice chip widgets in Flutter. Includes an interactive workout selector UI demonstration.

License

Notifications You must be signed in to change notification settings

flutterdude/flutter-custom-choice-chips

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flutter Multi-Select Workout Choice UI

How it looks

🚀 Description

This project demonstrates the creation of a modern, user-friendly multi-select workout selection screen in Flutter. It addresses the common problem of clunky and hard-to-scale single dropdown lists for choosing multiple items. The aim was to rebuild an old gym app's workout selection feature, transforming it into a clean, simple, and efficient interface where users can easily tap to select multiple workouts.

This repository showcases a simplified version of the solution, focusing on custom widget creation and local state management with setState.

✨ Features

  • Custom Choice Chip Widget: A tailor-made chip widget (ChoiceChipWidget) built from scratch for complete control over appearance and behavior.
    • Displays an icon and a title.
    • Visually changes based on selection state (selected/unselected).
    • Includes dynamic background color, content color, border color, and shadow color.
    • Customizable rounded corners and border.
    • Shadow effect on selection for a "pop" effect.
    • Built-in ripple effect on tap using InkWell.
    • Error handling for image assets.
  • Multi-Select Functionality: Allows users to tap and select multiple workout options.
  • Dynamic Chip Generation: Workout chips are dynamically generated from a list/map of available workouts.
  • State Management for Selections:
    • Uses a Map<String, bool> to track the selection status of each workout.
    • Manages state using StatefulWidget and setState() for UI updates upon interaction.
  • Responsive Layout with Wrap: Chips are displayed in a Wrap widget, allowing them to flow to the next line if horizontal space is limited.
    • Chips are centered within the wrap.
    • Adjustable spacing between chips (runSpacing) and internal padding for better visual appeal.
  • Conditional Continue Button: An ActionButton is provided which:
    • Can be enabled/disabled based on logic.
    • In this project, it's enabled only when the user has selected two or more workouts.
  • Clean UI Structure: Utilizes Scaffold, AppBar, Column, Row, Center, and Spacer for a well-organized page layout.

🎯 Problem It Solves

Traditional single dropdown lists for multiple selections can be:

  • Clunky and Hard to Use: Requiring users to scroll through long lists.
  • Difficult to Scale: Adding more options makes the dropdown even more cumbersome.
  • Less Engaging: Lacks immediate visual feedback for selected items.

This project provides a solution that is:

  • Intuitive: Users can simply tap to select/deselect.
  • Efficient: All options (or many) can be visible at once.
  • Scalable: Easily handles a growing list of workout options.
  • Visually Appealing: Modern look and feel with custom styling.

🛠️ Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.

Prerequisites

  • Flutter SDK installed. (See Flutter documentation)
  • An IDE like IntelliJ IDEA, Android Studio, or VS Code with the Flutter plugin.

Installation

  1. Clone the repository:

    git clone [https://github.com/YOUR_USERNAME/YOUR_REPOSITORY_NAME.git](https://github.com/YOUR_USERNAME/YOUR_REPOSITORY_NAME.git)
    cd YOUR_REPOSITORY_NAME
  2. Create an assets/icons/ folder: At the root of your Flutter project, create a folder named assets. Inside assets, create another folder named icons.

    project_root/
    ├── assets/
    │   └── icons/
    │       └── your_icon1.png
    │       └── your_icon2.png
    │       └── ...
    └── lib/
    └── ...
    
    • Recommendation: Place your workout icon images (e.g., cardio.png, strength.png) inside the assets/icons/ folder. The transcript implies using PNGs, but other formats might work.
  3. Declare assets in pubspec.yaml: Open your pubspec.yaml file and add your assets folder under the flutter section. Ensure correct indentation.

    flutter:
      uses-material-design: true
      assets:
        - assets/icons/ # Add this line
  4. Install dependencies: Run the following command in your project's root directory:

    flutter pub get
  5. Run the project: Connect a device or start an emulator/simulator, then run:

    flutter run
    • A hot restart (or full stop and restart) might be necessary after adding assets for Flutter to recognize them.

🔩 Usage

The main focus of this project is the WorkoutSelectionPage and the custom ChoiceChipWidget.

workout_selection_page.dart

This stateful widget sets up the main screen:

  1. Initialization:

    • A Map<String, bool> called workoutSelections stores the available workouts and their selection state (e.g., {'Cardio': false, 'Strength': false}).
    • A Map<String, String> called workoutIcons stores the path to the icon for each workout (e.g., {'Cardio': 'assets/icons/cardio.png'}).
    • An integer count tracks the number of selected workouts.
  2. UI Structure:

    • A Scaffold provides the basic page layout with an AppBar.
    • The body uses a Column with MainAxisAlignment.spaceBetween to distribute content.
    • An instructional Text widget ("Choose two or more to continue") is displayed at the top.
    • A Center widget contains a Wrap widget.
      • Recommendation: A screenshot of the Wrap widget displaying multiple choice chips would be ideal here.
    • The Wrap widget dynamically generates ChoiceChipWidget instances based on the workoutSelections map.
      • Each chip's isSelected state is tied to the map's boolean value.
      • The onTap callback updates the workoutSelections map and the count using setState().
    • A Spacer pushes the content upwards.
    • An ActionButton (the "Continue" button) is at the bottom, wrapped in a Row for centering. Its isEnabled property is dynamically set based on count > 1.

choice_chip_widget.dart

This stateless widget defines the custom choice chip:

  1. Parameters:

    • iconPath: String for the asset image.
    • title: String for the workout name.
    • isSelected: Boolean indicating if the chip is currently selected.
    • onTap: Callback function executed when the chip is tapped.
  2. Appearance:

    • Uses an InkWell for tap effects, with borderRadius to match the chip's shape.
    • A Container with BoxDecoration styles the chip:
      • Dynamic background color, border color, and shadow based on isSelected.
      • Rounded corners (BorderRadius.circular(24)).
    • A Row arranges the icon (Image.asset) and text (Text).
      • Recommendation: Screenshots showing the chip in its selected and unselected states would be beneficial here. Also, a screenshot showing the fixed InkWell shadow.

Making it Interactive

  • Tapping a ChoiceChipWidget toggles its selection state.
  • The setState() call in WorkoutSelectionPage rebuilds the UI to reflect the change.
  • The "Continue" button becomes active only when two or more workouts are selected.

🧪 Testing

Writing tests is a crucial part of developing robust and maintainable Flutter applications. This includes:

  • Widget Tests: To verify that your widgets look and behave as expected.
  • Unit Tests: To test individual functions, methods, or classes.
  • Integration Tests: To test complete app scenarios or larger parts of your app.

For the brevity of this demonstration project and the associated tutorial, detailed test cases have been excluded. However, in a real-world application, you would want to write comprehensive tests for the ChoiceChipWidget, the WorkoutSelectionPage, and the state management logic.

📺 Watch The Demo

For a detailed walkthrough and live demonstration of building this project, check out the YouTube video: Watch the full video tutorial here!

🤝 Contributing

Contributions are welcome! If you have suggestions for improvements or find any issues, feel free to:

  1. Fork the repository.
  2. Create a new branch (git checkout -b feature/YourFeature or bugfix/YourBugfix).
  3. Make your changes.
  4. Commit your changes (git commit -m 'Add some feature').
  5. Push to the branch (git push origin feature/YourFeature).
  6. Open a Pull Request.

Please make sure to update tests as appropriate if you add new features or fix bugs.

❓ Need Help?

If you're working on your own Flutter project and need assistance, or if you have questions about this example, feel free to reach out. You can mention the contact method provided in the video or open an issue on this repository for project-specific questions.

📝 License

This project is licensed under the MIT License.

About

Reusable custom multi-select choice chip widgets in Flutter. Includes an interactive workout selector UI demonstration.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published