Skip to main content

SelectorListAppi

A flexible horizontal selector widget that displays items as chips or cards with optional icons, supporting single selection and customizable styling.

Features

  • Horizontal Layout: Displays items in a scrollable horizontal list
  • Single Selection: Select one item from the list
  • Icon Support: Optional icons for each item
  • Flexible Sizing: Customizable width, height, and spacing
  • Scrollable: Automatically scrollable when content exceeds container width
  • Custom Styling: Configurable text colors, alignment, and dimensions
  • Form Integration: Works seamlessly with form validation
  • Responsive Design: Adapts to different screen sizes and orientations

Usage

Basic Selector List

SelectorListAppi(
selected: _selectedOption,
dat: ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
onTap: (selectedValue) {
setState(() => _selectedOption = selectedValue);
},
)

Selector List with Icons

SelectorListAppi(
selected: _selectedCategory,
dat: ['Home', 'Work', 'Personal', 'Travel'],
icons: [
Icons.home,
Icons.work,
Icons.person,
Icons.flight,
],
onTap: (selectedValue) {
setState(() => _selectedCategory = selectedValue);
},
)

Customized Selector List

SelectorListAppi(
selected: _selectedPriority,
dat: ['Low', 'Medium', 'High', 'Critical'],
heading: 'Priority Level',
mandatory: true,
minWidth: 80,
chipHeight: 45,
spacing: 12,
iconHeight: 20,
iconWidth: 20,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.grey[600],
crossAlignment: CrossAxisAlignment.center,
onTap: (selectedValue) {
setState(() => _selectedPriority = selectedValue);
},
)

Parameters

| Name | Type | Description | Default | |------|------|-------------|---------|| | selected | String | Required. Currently selected value | - | | dat | List<String> | Required. List of options to display | - | | onTap | Function(String) | Required. Callback when an item is tapped | - | | icons | List<IconData>? | Optional list of icons for each item | null | | heading | String? | Optional heading text above the selector | null | | mandatory | bool? | Whether the field is required (shows asterisk) | false | | minWidth | double? | Minimum width for each chip | null | | chipHeight | double? | Height of each chip | null | | spacing | double? | Horizontal spacing between chips | 8.0 | | iconPadding | EdgeInsets? | Padding around icons | null | | iconHeight | double? | Height of icons | null | | iconWidth | double? | Width of icons | null | | crossAlignment | CrossAxisAlignment? | Vertical alignment of items | CrossAxisAlignment.center | | scrollable | bool? | Whether the list should be scrollable | true | | selectedTextColor | Color? | Text color for selected item | null | | unselectedTextColor | Color? | Text color for unselected items | null |

Behavior

Selection

  • Only one item can be selected at a time
  • Tapping an item selects it and deselects others
  • Selected item is visually highlighted
  • Callback is triggered on every selection change

Layout

  • Items are arranged horizontally
  • Automatically scrollable when content exceeds container width
  • Spacing between items is customizable
  • Icons (if provided) are displayed above text labels

Styling

  • Selected and unselected items have different visual states
  • Text colors can be customized for both states
  • Icon and chip dimensions are configurable
  • Supports custom alignment and spacing

Best Practices

  1. Item Count: Keep the number of items reasonable for horizontal scrolling
  2. Icon Consistency: If using icons, provide them for all items or none
  3. Text Length: Keep item labels short for better horizontal layout
  4. Spacing: Use appropriate spacing for touch targets (minimum 44px)
  5. Color Contrast: Ensure good contrast between selected/unselected states
  6. Accessibility: Provide meaningful labels and ensure proper touch targets

Examples

Category Selection

SelectorListAppi(
selected: _selectedCategory,
dat: ['All', 'Work', 'Personal', 'Shopping', 'Health'],
icons: [
Icons.apps,
Icons.work,
Icons.person,
Icons.shopping_cart,
Icons.health_and_safety,
],
heading: 'Category',
chipHeight: 50,
spacing: 10,
iconHeight: 24,
iconWidth: 24,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.grey[700],
onTap: (category) {
setState(() => _selectedCategory = category);
_filterByCategory(category);
},
)

Priority Selector

SelectorListAppi(
selected: _selectedPriority,
dat: ['Low', 'Medium', 'High', 'Urgent'],
heading: 'Priority',
mandatory: true,
minWidth: 70,
chipHeight: 40,
spacing: 8,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.black87,
onTap: (priority) {
setState(() => _selectedPriority = priority);
_updateTaskPriority(priority);
},
)

Status Filter

SelectorListAppi(
selected: _selectedStatus,
dat: ['Pending', 'In Progress', 'Completed', 'Cancelled'],
icons: [
Icons.schedule,
Icons.play_arrow,
Icons.check_circle,
Icons.cancel,
],
heading: 'Filter by Status',
chipHeight: 45,
spacing: 12,
iconHeight: 20,
iconWidth: 20,
crossAlignment: CrossAxisAlignment.center,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.grey[600],
onTap: (status) {
setState(() => _selectedStatus = status);
_applyStatusFilter(status);
},
)

Time Period Selector

SelectorListAppi(
selected: _selectedPeriod,
dat: ['Today', 'This Week', 'This Month', 'This Year'],
heading: 'Time Period',
minWidth: 90,
chipHeight: 38,
spacing: 10,
selectedTextColor: Colors.blue[700],
unselectedTextColor: Colors.grey[500],
onTap: (period) {
setState(() => _selectedPeriod = period);
_loadDataForPeriod(period);
},
)

Form Integration

Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectorListAppi(
selected: _selectedType,
dat: ['Income', 'Expense', 'Transfer'],
icons: [
Icons.arrow_downward,
Icons.arrow_upward,
Icons.swap_horiz,
],
heading: 'Transaction Type',
mandatory: true,
chipHeight: 50,
spacing: 15,
iconHeight: 24,
iconWidth: 24,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.black87,
onTap: (type) {
setState(() => _selectedType = type);
_updateFormFields(type);
},
),
SizedBox(height: 20),
SelectorListAppi(
selected: _selectedFrequency,
dat: ['Once', 'Daily', 'Weekly', 'Monthly'],
heading: 'Frequency',
minWidth: 80,
chipHeight: 40,
spacing: 10,
selectedTextColor: Colors.green[700],
unselectedTextColor: Colors.grey[600],
onTap: (frequency) {
setState(() => _selectedFrequency = frequency);
},
),
],
)

Scrollable Long List

SelectorListAppi(
selected: _selectedCountry,
dat: [
'USA', 'Canada', 'UK', 'Germany', 'France',
'Italy', 'Spain', 'Australia', 'Japan', 'India'
],
heading: 'Select Country',
scrollable: true,
minWidth: 80,
chipHeight: 42,
spacing: 8,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.black54,
onTap: (country) {
setState(() => _selectedCountry = country);
_loadCountryData(country);
},
)

Custom Styled Selector

SelectorListAppi(
selected: _selectedTheme,
dat: ['Light', 'Dark', 'Auto'],
icons: [
Icons.light_mode,
Icons.dark_mode,
Icons.auto_mode,
],
heading: 'Theme Preference',
chipHeight: 55,
spacing: 15,
iconHeight: 28,
iconWidth: 28,
iconPadding: EdgeInsets.only(bottom: 4),
crossAlignment: CrossAxisAlignment.center,
selectedTextColor: Colors.white,
unselectedTextColor: Colors.grey[700],
onTap: (theme) {
setState(() => _selectedTheme = theme);
_applyTheme(theme);
},
)

See Also