DebounceController
DebounceController
is a Flutter package that provides a simple yet powerful way to handle
debounced text input operations with support for asynchronous functions. It leverages the GetX
package for reactive state management and allows for easy integration of debounce functionality in
your Flutter applications.
Features
- Debounced Text Input: Prevents frequent calls to a function while typing.
- Asynchronous Operation Support: Handle complex operations like API requests seamlessly.
- Multiple Controller Support: Create and manage multiple
DebounceController
instances using unique tags. - Error Handling: Custom error handling with callback support.
- Reactive State Management: Built on top of
GetX
, providing a reactive experience.
Installation
Add the following to your pubspec.yaml
file:
dependencies:
debounce_controller: <latest_version>
get: <latest_version>
Then run flutter pub get
to install the package.
Usage
1. Import the package
import 'package:debounce_controller/debounce_controller.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
2. Create a DebounceController
You can create a DebounceController
instance using Get.put
with an optional tag if you need
multiple controllers:
final searchController1 = Get.put(
() =>
DebounceController<String>(
futureOperation: _searchOperation,
),
tag: 'searchController1',
);
3. Implement the Future Operation
The DebounceController
requires a Future<List<T>> Function(TextEditingController)
to process the
text input:
Future<List<String>> _searchOperation(TextEditingController controller) async {
await Future.delayed(Duration(seconds: 1)); // Simulate network delay
return List.generate(5, (index) => 'Result ${index + 1} for "${controller.text}"');
}
4. Build the UI
Use the DebounceController
in your UI, reacting to data and loading states:
Obx
(
() {
if (searchController1.loading.value) {
return CircularProgressIndicator();
}
return Expanded(
child: ListView.builder(
itemCount: searchController1.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(searchController1.data[index].toString()),
);
},
),
);
})
,
5. Full Example
Here’s a complete example in main.dart
:
import 'package:debounce_controller/debounce_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const GetMaterialApp(
title: 'DebounceController Example',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
// Creating multiple DebounceController instances using tags.
final searchController1 = Get.put(
DebounceController<String>(
futureOperation: _searchOperation,
),
tag: 'searchController1',
);
final searchController2 = Get.put(
DebounceController<String>(
futureOperation: _searchOperation,
),
tag: 'searchController2',
);
return Scaffold(
appBar: AppBar(title: const Text('DebounceController Example')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: searchController1.textEditingController,
decoration: const InputDecoration(
labelText: 'Search 1',
border: OutlineInputBorder(),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: searchController2.textEditingController,
decoration: const InputDecoration(
labelText: 'Search 2',
border: OutlineInputBorder(),
),
),
),
Obx(() {
if (searchController1.loading.value) {
return const CircularProgressIndicator();
}
return Expanded(
child: ListView.builder(
itemCount: searchController1.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(searchController1.data[index].toString()),
);
},
),
);
}),
],
),
);
}
// Example async search operation, replace with actual implementation.
Future<List<String>> _searchOperation(TextEditingController controller) async {
await Future.delayed(const Duration(seconds: 1)); // Simulate network delay
return List.generate(5, (index) => 'Result ${index + 1} for "${controller.text}"');
}
}
6. Error Handling
You can handle errors using the onError
parameter:
final searchController = Get.put(
() =>
DebounceController<String>(
futureOperation: _searchOperation,
onError: (error, stackTrace) {
print('Error: $error');
},
),
);