flutter/lib/pages/search/index.dart

215 lines
6.6 KiB
Dart
Raw Normal View History

2025-08-27 18:14:45 +08:00
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:loopin/components/my_toast.dart';
import '../../behavior/custom_scroll_behavior.dart';
class SearchPage extends StatefulWidget {
const SearchPage({super.key});
@override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
final TextEditingController _searchController = TextEditingController();
final GetStorage _storage = GetStorage();
List<dynamic> _searchHistory = [];
@override
void initState() {
super.initState();
_loadSearchHistory();
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
// 加载搜索历史
void _loadSearchHistory() {
setState(() {
_searchHistory = _storage.read('searchHistory') ?? [];
});
}
// 保存搜索历史
void _saveSearchHistory() {
_storage.write('searchHistory', _searchHistory);
}
// 添加搜索项
void _addSearchItem(String query) {
if (query.trim().isEmpty) return;
setState(() {
// 移除重复项
_searchHistory.remove(query);
// 添加到开头
_searchHistory.insert(0, query);
// 暂时限制历史记录数量未10条
if (_searchHistory.length > 10) {
_searchHistory = _searchHistory.sublist(0, 10);
}
});
_saveSearchHistory();
}
// 清除单个搜索历史
void _removeSearchItem(int index) {
setState(() {
_searchHistory.removeAt(index);
});
_saveSearchHistory();
}
// 清除所有搜索历史
void _clearAllHistory() {
setState(() {
_searchHistory.clear();
});
_saveSearchHistory();
MyToast().tip(
title: '搜索历史已清除',
position: 'center',
type: 'success',
);
}
// 执行搜索
void _performSearch() {
final searchWords = _searchController.text.trim();
if (searchWords.isNotEmpty) {
_addSearchItem(searchWords);
_searchController.clear();
FocusScope.of(context).unfocus();
// 去搜索结果页支持带着搜索文字和搜索tab索引
Get.toNamed('/search-result', arguments: searchWords);
} else {
MyToast().tip(
title: '请输入搜索内容',
position: 'center',
type: 'error',
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.black,
foregroundColor: Colors.white,
elevation: 0,
title: Container(
height: 40,
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(20),
),
child: TextField(
controller: _searchController,
style: const TextStyle(color: Colors.white, fontSize: 16),
decoration: InputDecoration(
hintText: '请输入内容~',
hintStyle: TextStyle(color: Colors.grey[500], fontSize: 16),
border: InputBorder.none,
prefixIcon: Icon(Icons.search, color: Colors.grey[500], size: 20),
suffixIcon: _searchController.text.isNotEmpty
? IconButton(
icon: Icon(Icons.close, color: Colors.grey[500], size: 20),
onPressed: () {
_searchController.clear();
setState(() {});
},
)
: null,
contentPadding: const EdgeInsets.symmetric(vertical: 10),
),
onSubmitted: (_) => _performSearch(),
onChanged: (_) => setState(() {}),
),
),
actions: [
TextButton(
onPressed: _performSearch,
child: const Text('搜索', style: TextStyle(color: Colors.white, fontSize: 16)),
),
],
),
body: ScrollConfiguration(
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 搜索历史
if (_searchHistory.isNotEmpty) ...[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'搜索历史',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold
),
),
TextButton(
onPressed: _clearAllHistory,
child: const Text(
'清除所有',
style: TextStyle(color: Colors.grey, fontSize: 14),
),
),
],
),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: List.generate(_searchHistory.length, (index) {
return GestureDetector(
onTap: () {
_searchController.text = _searchHistory[index];
_performSearch();
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.grey[800],
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_searchHistory[index],
style: const TextStyle(color: Colors.white),
),
const SizedBox(width: 6),
GestureDetector(
onTap: () => _removeSearchItem(index),
child: Icon(Icons.close, size: 16, color: Colors.grey[500]),
),
],
),
),
);
}),
),
const SizedBox(height: 24),
],
],
),
),
),
);
}
}