To avoid repeated loading of dropdown items (like courses, universities, etc.) on every page, you can use caching or a singleton pattern to load the items once and reuse them throughout your app. Here are the best solutions:
Solution 1: Use a Global Cache (Shared State)
You can store the dropdown items in a singleton service class or global variable and load them only once.
Step 1: Create a Singleton Service
dartclass DropdownService { static final DropdownService _instance = DropdownService._internal(); factory DropdownService() { return _instance; } DropdownService._internal(); List<Map<String, String>> courseItems = []; List<Map<String, String>> universityItems = []; bool isLoaded = false; Future<void> loadDropdowns() async { if (!isLoaded) { // Load only if not loaded before courseItems = await fetchGroupitems("2"); // Load Courses universityItems = await fetchGroupitems("3"); // Load Universities isLoaded = true; } } }
Step 2: Load Data Once in
main.dart
dartvoid main() async { WidgetsFlutterBinding.ensureInitialized(); await DropdownService().loadDropdowns(); // Load only once runApp(MyApp()); }
Step 3: Use in Any Page Without Reloading
dartclass MyDropdownPage extends StatefulWidget { @override _MyDropdownPageState createState() => _MyDropdownPageState(); } class _MyDropdownPageState extends State<MyDropdownPage> { List<Map<String, String>> courseItems = DropdownService().courseItems; String selectedCourse = "0"; @override Widget build(BuildContext context) { return DropdownButtonFormField<String>( decoration: InputDecoration(labelText: "Select Course"), value: selectedCourse, items: courseItems.map((item) { return DropdownMenuItem<String>( value: item['id'], child: Text(item['name'] ?? ""), ); }).toList(), onChanged: (value) { setState(() { selectedCourse = value!; }); }, ); } }
Solution 2: Store Dropdown Data in
SharedPreferences
You can store the dropdown values in SharedPreferences and only update them when needed.
Step 1: Save Data After Fetching
dartimport 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; Future<void> saveDropdownData(String key, List<Map<String, String>> data) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString(key, jsonEncode(data)); }
Step 2: Load Data from Cache
dartFuture<List<Map<String, String>>> loadDropdownData(String key) async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? data = prefs.getString(key); if (data != null) { return List<Map<String, String>>.from(jsonDecode(data)); } return []; }
Step 3: Fetch Data Only if Needed
dartFuture<void> fetchCourses() async { courseItems = await loadDropdownData("courses"); if (courseItems.isEmpty) { courseItems = await fetchGroupitems("2"); saveDropdownData("courses", courseItems); } }
This way, data is fetched from cache instead of calling the API repeatedly.
Solution 3: Use a Provider or Riverpod for State Management
If you're using Provider or Riverpod, you can store the dropdown values in the app state and access them without reloading.
Using Provider
dartimport 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class DropdownProvider with ChangeNotifier { List<Map<String, String>> courseItems = []; Future<void> loadDropdowns() async { if (courseItems.isEmpty) { courseItems = await fetchGroupitems("2"); notifyListeners(); // Notify UI to update } } }
Wrap Your App with Provider
dartvoid main() { runApp( ChangeNotifierProvider( create: (_) => DropdownProvider()..loadDropdowns(), child: MyApp(), ), ); }
Use in Any Page
dartDropdownButtonFormField<String>( value: selectedCourse, items: Provider.of<DropdownProvider>(context).courseItems.map((item) { return DropdownMenuItem<String>( value: item['id'], child: Text(item['name']), ); }).toList(), onChanged: (value) { setState(() { selectedCourse = value!; }); }, );
Which Solution Should You Use?
Solution When to Use? Singleton ( DropdownService
)If dropdown data is needed across multiple pages and should only be loaded once SharedPreferences Cache If you want dropdown data to persist even after the app restarts Provider/Riverpod If you're already using state management for better efficiency
No comments:
Post a Comment