customize_search_dropdown 0.0.2 copy "customize_search_dropdown: ^0.0.2" to clipboard
customize_search_dropdown: ^0.0.2 copied to clipboard

A customizable search dropdown widget for Flutter.

example/lib/main.dart

import 'package:customize_search_dropdown/custom_dropdown.dart';
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Dropdown Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Demo Data Models
  String? _selectedLocalItem;
  User? _selectedApiItem;
  List<String> _selectedMultiItems = [];

  // Local Data
  final List<String> _localItems = [
    "Apple",
    "Banana",
    "Cherry",
    "Date",
    "Elderberry",
    "Fig",
    "Grape",
    "Honeydew",
    "Kiwi",
    "Lemon",
    "Mango",
    "Nectarine",
    "Orange",
    "Papaya",
    "Quince",
    "Raspberry",
    "Strawberry",
    "Tangerine",
    "Ugli Fruit",
    "Vanilla Bean",
    "Watermelon",
  ];

  // API Simulation
  Future<List<User>> _getUsers(int page, String? query) async {
    await Future.delayed(const Duration(seconds: 1)); // Simulate network delay

    // Simulate a large database of users
    final List<User> allUsers = List.generate(
      100,
      (index) =>
          User(id: index, name: "User $index", email: "user$index@example.com"),
    );

    // Filter
    final filtered =
        query == null || query.isEmpty
            ? allUsers
            : allUsers
                .where(
                  (u) => u.name.toLowerCase().contains(query.toLowerCase()),
                )
                .toList();

    // Pagination
    const pageSize = 10;
    final start = (page - 1) * pageSize;
    if (start >= filtered.length) return [];

    final end = start + pageSize;
    return filtered.sublist(
      start,
      end > filtered.length ? filtered.length : end,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Custom Dropdown Demo"),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              "1. Simple Local Data Dropdown",
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 10),
            CustomDropdown<String>(
              hintText: "Select Fruit",
              items: _localItems,
              selectedItem: _selectedLocalItem,
              onChanged: (value) {
                setState(() => _selectedLocalItem = value);
              },
              headerDecoration: BoxDecoration(
                color: Colors.grey[200],
                borderRadius: BorderRadius.circular(8),
              ),
            ),

            const SizedBox(height: 40),

            const Text(
              "2. Multi-Selection Dropdown",
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 10),
            CustomDropdown<String>(
              hintText: "Select Multiple Fruits",
              items: _localItems,
              enableMultiSelection: true,
              selectedItems: _selectedMultiItems,
              onListChanged: (value) {
                setState(() => _selectedMultiItems = value);
              },
              headerDecoration: BoxDecoration(
                color: Colors.blue[50],
                borderRadius: BorderRadius.circular(8),
                border: Border.all(color: Colors.blue),
              ),
            ),

            const SizedBox(height: 40),

            const Text(
              "3. API Pagination + Search Dropdown",
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const Text(
              "Simulates network delay and pagination (10 per page)",
              style: TextStyle(fontSize: 12, color: Colors.grey),
            ),
            const SizedBox(height: 10),
            CustomDropdown<User>(
              hintText: "Select User (Async)",
              searchHintText: "Search by name...",
              futureRequest: _getUsers,
              itemsPerPage: 10,
              selectedItem: _selectedApiItem,

              // Custom Label Function
              itemLabel: (user) => user.name,

              onChanged: (value) {
                setState(() => _selectedApiItem = value);
              },

              // Custom List Item using the builder
              listItemBuilder: (context, item, isSelected, onTap) {
                return ListTile(
                  selected: isSelected,
                  selectedTileColor: Colors.deepPurple.withValues(alpha: 0.1),
                  onTap: onTap,
                  leading: CircleAvatar(child: Text(item.name[0])),
                  title: Text(item.name),
                  subtitle: Text(item.email),
                  trailing:
                      isSelected
                          ? const Icon(Icons.check, color: Colors.deepPurple)
                          : null,
                );
              },
            ),

            const SizedBox(height: 40),

            const Text(
              "4. Custom Styling & Header",
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 10),
            CustomDropdown<String>(
              hintText: "Styled Dropdown",
              items: _localItems,
              selectedItem: _selectedLocalItem,
              onChanged: (value) {
                setState(() => _selectedLocalItem = value);
              },
              headerBuilder: (context, selectedItem, selectedItems) {
                return Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    gradient: const LinearGradient(
                      colors: [Colors.blue, Colors.purple],
                    ),
                    borderRadius: BorderRadius.circular(20),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.black26,
                        blurRadius: 4,
                        offset: Offset(0, 2),
                      ),
                    ],
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        selectedItem ?? "Choose Awesome Fruit",
                        style: const TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const Icon(
                        Icons.arrow_drop_down_circle,
                        color: Colors.white,
                      ),
                    ],
                  ),
                );
              },
              dropdownDecoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(20),
                border: Border.all(color: Colors.purple.shade100),
                boxShadow: [
                  BoxShadow(
                    color: Colors.purple.withValues(alpha: 0.1),
                    blurRadius: 10,
                    offset: Offset(0, 5),
                  ),
                ],
              ),
            ),

            const SizedBox(height: 400), // Spacing to test scrolling behavior
          ],
        ),
      ),
    );
  }
}

class User {
  final int id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});

  @override
  String toString() => name;
}
3
likes
0
points
62
downloads

Publisher

unverified uploader

Weekly Downloads

A customizable search dropdown widget for Flutter.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

cupertino_icons, flutter

More

Packages that depend on customize_search_dropdown