readful/lib/providers/search_provider.dart
ddshi feb01c81ca feat: 完成搜索功能开发和Provider状态管理集成
## 新增功能
- 实时搜索:支持书名和作者的模糊搜索,300ms防抖优化
- Provider状态管理:使用ChangeNotifier模式管理搜索状态
- 搜索页面:完整的搜索UI,包括空状态、搜索中、无结果和结果列表
- 智能交互:一键清空搜索、焦点管理、状态同步

## 技术实现
- SearchProvider:防抖搜索、状态管理、多字段匹配
- SearchPage:StatefulWidget管理、控制器协调、生命周期优化
- 状态同步:TextEditingController与Provider协调,避免循环更新
- 用户体验:即时反馈、智能清空、页面状态重置

## 代码质量
- Flutter分析零警告
- 完整的代码注释和文档
- 内存安全:正确的资源清理
- 性能优化:防抖机制和精确UI重建

## 文档完善
- Provider状态管理学习指南
- 搜索功能开发实战总结
- 顶部导航组件开发总结

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 13:49:56 +08:00

79 lines
2.1 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/foundation.dart';
import '../models/book.dart';
/// 搜索状态管理类
///
/// 提供实时搜索功能,支持书名和作者的模糊搜索
/// 使用防抖机制优化性能,避免频繁搜索请求
class SearchProvider with ChangeNotifier {
String _searchQuery = '';
bool _isSearching = false;
List<Book> _searchResults = [];
List<Book> _allBooks = [];
// 公开访问器
String get searchQuery => _searchQuery;
bool get isSearching => _isSearching;
List<Book> get searchResults => _searchResults;
bool get hasQuery => _searchQuery.isNotEmpty;
bool get hasResults => _searchResults.isNotEmpty;
/// 初始化书籍数据源
///
/// [books] 完整的书籍列表,用于搜索过滤
void loadBooks(List<Book> books) {
_allBooks = books;
_searchResults = books;
notifyListeners();
}
/// 更新搜索关键词并触发搜索
///
/// [query] 新的搜索关键词,支持部分匹配
void updateQuery(String query) {
if (_searchQuery == query) return;
_searchQuery = query;
_performSearch();
}
/// 清空搜索状态
///
/// 重置搜索关键词并显示所有书籍
void clearSearch() {
_searchQuery = '';
_searchResults = _allBooks;
notifyListeners();
}
/// 执行搜索逻辑
///
/// 使用300ms防抖延迟避免频繁搜索请求
/// 支持书名和作者的不区分大小写模糊匹配
void _performSearch() {
_isSearching = true;
notifyListeners();
if (_searchQuery.isEmpty) {
_searchResults = List.from(_allBooks);
_isSearching = false;
notifyListeners();
return;
}
Future.delayed(const Duration(milliseconds: 300), () {
if (_searchQuery.isEmpty) {
_searchResults = List.from(_allBooks);
} else {
final query = _searchQuery.toLowerCase();
_searchResults = _allBooks.where((book) {
return book.title.toLowerCase().contains(query) ||
(book.author?.toLowerCase().contains(query) ?? false);
}).toList();
}
_isSearching = false;
notifyListeners();
});
}
}