A highly customizable dropdown package for Flutter with overlay-based rendering, smooth animations, and specialized variants for different content types.
- π¨ Highly Customizable: Complete control over appearance and behavior
- π± Overlay-based Rendering: Better positioning and visual effects
- β¨ Smooth Animations: Scale and fade effects with configurable timing
- π― Outside-tap Dismissal: Automatic closure when tapping outside
- π Dynamic Width: Fixed, min/max width constraints, or content-based sizing
- π Independent Menu Width: Set menu width separately from button with min/max constraints and alignment control
- π Text Overflow Control: Ellipsis, fade, clip, or visible overflow options
- π Multiple Variants: Generic BasicDropdownButton and specialized TextOnlyDropdownButton
- π¨ Shared Theme System: Consistent styling across all dropdown variants
- π Custom Scrollbar: Scrollbar theming with colors, thickness, and visibility options
- βΏ Accessibility Support: Screen reader friendly with proper semantics
![]() |
![]() |
| Basic Text Dropdown Simple text options with customizable styles |
Icon + Text Dropdown Rich content with icons and hover effects |
Generic dropdown supporting any widget as items with complete customization.
Specialized dropdown for text content with precise text rendering control.
Add to your pubspec.yaml:
dependencies:
flutter_dropdown_button: ^1.6.1Import the package:
import 'package:flutter_dropdown_button/flutter_dropdown_button.dart';BasicDropdownButton<String>(
items: [
DropdownItem(
value: 'apple',
child: Row(
children: [
Icon(Icons.apple),
SizedBox(width: 8),
Text('Apple'),
],
),
),
DropdownItem(
value: 'banana',
child: Text('Banana'),
),
],
value: selectedValue,
hint: Text('Select a fruit'),
onChanged: (value) {
setState(() {
selectedValue = value;
});
},
)TextOnlyDropdownButton(
items: [
'Short',
'Medium length text',
'Very long text that demonstrates overflow behavior',
],
value: selectedText,
hint: 'Select an option',
maxWidth: 200,
config: TextDropdownConfig(
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
onChanged: (value) {
setState(() {
selectedText = value;
});
},
)TextOnlyDropdownButton(
// ... other properties
theme: DropdownStyleTheme(
dropdown: DropdownTheme(
borderRadius: 12.0,
elevation: 4.0,
),
scroll: DropdownScrollTheme(
thickness: 8.0,
thumbColor: Colors.blue,
// Enable scroll gradient indicators
showScrollGradient: true,
gradientHeight: 20.0,
gradientColors: [
Colors.white,
Colors.white.withOpacity(0.5),
Colors.white.withOpacity(0.0),
],
),
),
)TextOnlyDropdownButton(
// ... other properties
config: TextDropdownConfig(
overflow: TextOverflow.fade,
maxLines: 2,
textStyle: TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
)BasicDropdownButton<String>(
// ... other properties
maxWidth: 300, // Maximum width constraint
minWidth: 150, // Minimum width constraint
// OR
width: 250, // Fixed width
)TextOnlyDropdownButton(
// ... other properties
width: 120, // Button width
minMenuWidth: 250, // Menu minimum width (wider than button)
maxMenuWidth: 400, // Menu maximum width
menuAlignment: MenuAlignment.left, // left (default), center, or right
)Show fade gradients at the edges when content is scrollable:
TextOnlyDropdownButton(
items: longItemList,
height: 200, // Constrain height to enable scrolling
theme: DropdownStyleTheme(
scroll: DropdownScrollTheme(
showScrollGradient: true, // Enable gradient indicators
gradientHeight: 24.0, // Height of gradient effect
gradientColors: [ // Custom gradient colors (optional)
Colors.white, // Opaque at edge
Colors.white.withOpacity(0.5), // Semi-transparent
Colors.white.withOpacity(0.0), // Fully transparent
],
),
),
)The gradient automatically appears at the top when you can scroll up and at the bottom when you can scroll down.
Need to close any open dropdown before navigation or other actions? Use the static closeAll() method:
// Close dropdown before navigation
void navigateToHome() {
DropdownMixin.closeAll(); // Immediately close any open dropdown
Navigator.pushNamedAndRemoveUntil(
context,
'/home',
(route) => false,
);
}
// Close dropdown before showing dialog
void showDialog() {
DropdownMixin.closeAll();
showDialog(...);
}Note: Dropdowns are automatically cleaned up during normal navigation (widget disposal). Use closeAll() only when you need explicit control over when the dropdown closes.
For detailed documentation and advanced usage examples, see:
Check out the example app for a comprehensive demonstration of all features and customization options.
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for a detailed list of changes and version history.

