import 'package:flutter/material.dart'; /// 阅读搜索栏组件 class ReadingSearchBar extends StatefulWidget { final Function(String) onSearch; final String? initialQuery; final String hintText; const ReadingSearchBar({ super.key, required this.onSearch, this.initialQuery, this.hintText = '搜索文章标题、内容或标签...', }); @override State createState() => _ReadingSearchBarState(); } class _ReadingSearchBarState extends State { late TextEditingController _controller; final FocusNode _focusNode = FocusNode(); @override void initState() { super.initState(); _controller = TextEditingController(text: widget.initialQuery); // 自动聚焦 WidgetsBinding.instance.addPostFrameCallback((_) { _focusNode.requestFocus(); }); } @override void dispose() { _controller.dispose(); _focusNode.dispose(); super.dispose(); } void _performSearch() { final query = _controller.text.trim(); if (query.isNotEmpty) { widget.onSearch(query); } } @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题 const Text( '搜索文章', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 16), // 搜索输入框 TextField( controller: _controller, focusNode: _focusNode, decoration: InputDecoration( hintText: widget.hintText, hintStyle: TextStyle(color: Colors.grey[500]), prefixIcon: const Icon( Icons.search, color: Color(0xFF2196F3), ), suffixIcon: _controller.text.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: () { _controller.clear(); setState(() {}); }, ) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey[300]!), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide( color: Color(0xFF2196F3), width: 2, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey[300]!), ), contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), ), onChanged: (value) { setState(() {}); }, onSubmitted: (_) => _performSearch(), textInputAction: TextInputAction.search, ), const SizedBox(height: 16), // 搜索建议 _buildSearchSuggestions(), const SizedBox(height: 20), // 操作按钮 Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text( '取消', style: TextStyle(color: Colors.grey[600]), ), ), const SizedBox(width: 12), ElevatedButton( onPressed: _controller.text.trim().isNotEmpty ? _performSearch : null, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF2196F3), foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 12, ), ), child: const Text('搜索'), ), ], ), ], ), ), ); } /// 构建搜索建议 Widget _buildSearchSuggestions() { final suggestions = [ '四级阅读', '六级阅读', '托福阅读', '雅思阅读', '商务英语', '日常对话', '科技文章', '新闻报道', ]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '热门搜索', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Colors.grey[700], ), ), const SizedBox(height: 8), Wrap( spacing: 8, runSpacing: 8, children: suggestions.map((suggestion) { return GestureDetector( onTap: () { _controller.text = suggestion; setState(() {}); _performSearch(); }, child: Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.grey[300]!), ), child: Text( suggestion, style: TextStyle( fontSize: 12, color: Colors.grey[700], ), ), ), ); }).toList(), ), ], ); } } /// 简化的搜索栏组件(用于嵌入页面) class ReadingSearchField extends StatefulWidget { final Function(String) onSearch; final Function()? onTap; final String? initialQuery; final bool enabled; const ReadingSearchField({ super.key, required this.onSearch, this.onTap, this.initialQuery, this.enabled = true, }); @override State createState() => _ReadingSearchFieldState(); } class _ReadingSearchFieldState extends State { late TextEditingController _controller; @override void initState() { super.initState(); _controller = TextEditingController(text: widget.initialQuery); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.all(16), child: TextField( controller: _controller, enabled: widget.enabled, onTap: widget.onTap, decoration: InputDecoration( hintText: '搜索文章...', hintStyle: TextStyle(color: Colors.grey[500]), prefixIcon: const Icon( Icons.search, color: Color(0xFF2196F3), ), suffixIcon: _controller.text.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: () { _controller.clear(); widget.onSearch(''); setState(() {}); }, ) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(25), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, contentPadding: const EdgeInsets.symmetric( horizontal: 20, vertical: 12, ), ), onChanged: (value) { setState(() {}); }, onSubmitted: widget.onSearch, textInputAction: TextInputAction.search, ), ); } }