multi_language_search_engine 1.0.1
multi_language_search_engine: ^1.0.1 copied to clipboard
A powerful Flutter plugin for multi-language search with Arabic and English support, fuzzy matching, and typo tolerance.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:multi_language_search_engine/multi_language_search_engine.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Multi-Language Search Engine Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const SearchDemoPage(),
);
}
}
class SearchDemoPage extends StatefulWidget {
const SearchDemoPage({super.key});
@override
State<SearchDemoPage> createState() => _SearchDemoPageState();
}
class _SearchDemoPageState extends State<SearchDemoPage> {
late SearchEngine _englishEngine;
late SearchEngine _arabicEngine;
final TextEditingController _searchController = TextEditingController();
List<Map<String, dynamic>> _searchResults = [];
bool _isEnglish = true;
// Sample data
final List<Map<String, dynamic>> _englishData = [
{'id': 1, 'name': 'John Doe', 'description': 'Software Engineer', 'department': 'Engineering'},
{'id': 2, 'name': 'Jane Smith', 'description': 'Product Manager', 'department': 'Product'},
{'id': 3, 'name': 'Bob Johnson', 'description': 'Designer', 'department': 'Design'},
{'id': 4, 'name': 'Alice Brown', 'description': 'Data Scientist', 'department': 'Data'},
{'id': 5, 'name': 'Charlie Wilson', 'description': 'DevOps Engineer', 'department': 'Engineering'},
{'id': 6, 'name': 'Diana Davis', 'description': 'Marketing Specialist', 'department': 'Marketing'},
{'id': 7, 'name': 'Edward Miller', 'description': 'Sales Representative', 'department': 'Sales'},
];
final List<Map<String, dynamic>> _arabicData = [
{'id': 1, 'name': 'أحمد محمد', 'description': 'مطور برمجيات', 'department': 'الهندسة'},
{'id': 2, 'name': 'فاطمة علي', 'description': 'مدير منتج', 'department': 'المنتج'},
{'id': 3, 'name': 'محمد حسن', 'description': 'مصمم', 'department': 'التصميم'},
{'id': 4, 'name': 'سارة أحمد', 'description': 'عالم بيانات', 'department': 'البيانات'},
{'id': 5, 'name': 'علي محمود', 'description': 'مهندس ديف أوبس', 'department': 'الهندسة'},
{'id': 6, 'name': 'لينا يوسف', 'description': 'أخصائي تسويق', 'department': 'التسويق'},
{'id': 7, 'name': 'كريم عبدالله', 'description': 'ممثل مبيعات', 'department': 'المبيعات'},
];
@override
void initState() {
super.initState();
_initializeSearchEngines();
}
void _initializeSearchEngines() {
_englishEngine = createSearchEngine(
data: _englishData,
languageCode: 'en',
);
_arabicEngine = createSearchEngine(
data: _arabicData,
languageCode: 'ar',
);
}
void _performSearch(String query) {
final engine = _isEnglish ? _englishEngine : _arabicEngine;
final results = engine.search(query);
setState(() {
_searchResults = results;
});
}
void _toggleLanguage() {
setState(() {
_isEnglish = !_isEnglish;
_searchController.clear();
_searchResults = [];
});
}
@override
Widget build(BuildContext context) {
final currentData = _isEnglish ? _englishData : _arabicData;
return Scaffold(
appBar: AppBar(
title: Text(_isEnglish ? 'English Search Demo' : 'Arabic Search Demo'),
actions: [
IconButton(
icon: Icon(_isEnglish ? Icons.language : Icons.language_outlined),
onPressed: _toggleLanguage,
tooltip: 'Switch Language',
),
],
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
labelText: _isEnglish ? 'Search employees...' : 'البحث عن الموظفين...',
hintText: _isEnglish
? 'Try: software, manager, design...'
: 'جرب: مطور، مدير، تصميم...',
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: const Icon(Icons.search),
onPressed: () => _performSearch(_searchController.text),
),
),
onChanged: _performSearch,
textDirection: _isEnglish ? TextDirection.ltr : TextDirection.rtl,
),
),
Expanded(
child: _searchResults.isEmpty && _searchController.text.isEmpty
? _buildDataPreview(currentData)
: _buildSearchResults(),
),
],
),
);
}
Widget _buildDataPreview(List<Map<String, dynamic>> data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
final item = data[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
title: Text(item['name']),
subtitle: Text('${item['description']} • ${item['department']}'),
leading: CircleAvatar(
child: Text('${item['id']}'),
),
),
);
},
);
}
Widget _buildSearchResults() {
if (_searchResults.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.search_off,
size: 64,
color: Colors.grey,
),
const SizedBox(height: 16),
Text(
_isEnglish ? 'No results found' : 'لم يتم العثور على نتائج',
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8),
Text(
_isEnglish
? 'Try a different search term'
: 'جرب مصطلح بحث مختلف',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
],
),
);
}
return ListView.builder(
itemCount: _searchResults.length,
itemBuilder: (context, index) {
final item = _searchResults[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
title: Text(item['name']),
subtitle: Text('${item['description']} • ${item['department']}'),
leading: CircleAvatar(
child: Text('${item['id']}'),
),
),
);
},
);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
}