debounce_controller 1.0.1 debounce_controller: ^1.0.1 copied to clipboard
A Flutter package for handling debounced text input with async operations using GetX, ideal for responsive search and data fetching.
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');
},
),
);