search: add timer to search only after 0.5s inactivity
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Sheet {
|
class Sheet {
|
||||||
@@ -37,32 +39,45 @@ class SheetsWidget extends StatefulWidget {
|
|||||||
class _SheetsWidgetState extends State<SheetsWidget> {
|
class _SheetsWidgetState extends State<SheetsWidget> {
|
||||||
late List<Sheet> filteredSheets;
|
late List<Sheet> filteredSheets;
|
||||||
final TextEditingController _searchController = TextEditingController();
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
Timer? _debounce;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
filteredSheets = widget.sheets;
|
filteredSheets = widget.sheets;
|
||||||
_searchController.addListener(_filterSheets);
|
_searchController.addListener(_onSearchChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_searchController.removeListener(_onSearchChanged);
|
||||||
_searchController.dispose();
|
_searchController.dispose();
|
||||||
|
_debounce?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onSearchChanged() {
|
||||||
|
if (_debounce?.isActive ?? false) _debounce!.cancel();
|
||||||
|
|
||||||
|
_debounce = Timer(const Duration(milliseconds: 500), () {
|
||||||
|
_filterSheets();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _filterSheets() {
|
void _filterSheets() {
|
||||||
setState(() {
|
setState(() {
|
||||||
String query = _searchController.text.toLowerCase().trim();
|
String query = _searchController.text.toLowerCase().trim();
|
||||||
List<String> terms = query.split(RegExp(r'\s+')); // Split by whitespace
|
List<String> terms = query.split(RegExp(r'\s+')); // Split by whitespace
|
||||||
|
|
||||||
filteredSheets = widget.sheets.where((sheet) {
|
filteredSheets =
|
||||||
|
widget.sheets.where((sheet) {
|
||||||
String name = sheet.name.toLowerCase();
|
String name = sheet.name.toLowerCase();
|
||||||
String composer = sheet.composerName.toLowerCase();
|
String composer = sheet.composerName.toLowerCase();
|
||||||
|
|
||||||
// Each term must be found in either the name or composer
|
// Each term must be found in either the name or composer
|
||||||
return terms
|
return terms.every(
|
||||||
.every((term) => name.contains(term) || composer.contains(term));
|
(term) => name.contains(term) || composer.contains(term),
|
||||||
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -82,7 +97,8 @@ class _SheetsWidgetState extends State<SheetsWidget> {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search...',
|
hintText: 'Search...',
|
||||||
prefixIcon: const Icon(Icons.search),
|
prefixIcon: const Icon(Icons.search),
|
||||||
suffixIcon: _searchController.text.isNotEmpty
|
suffixIcon:
|
||||||
|
_searchController.text.isNotEmpty
|
||||||
? IconButton(
|
? IconButton(
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(Icons.clear),
|
||||||
onPressed: _clearSearch,
|
onPressed: _clearSearch,
|
||||||
|
|||||||
Reference in New Issue
Block a user