Flutter中英互译助手 - 完整开发教程
项目简介
这是一个使用Flutter开发的中英互译助手应用,提供实时翻译、历史记录、常用短语和收藏管理等功能。应用采用本地词典的方式实现翻译,无需网络连接,适合学习Flutter文本处理和数据管理。
运行效果图





核心特性
- 🔄 中英互译:支持中英文双向翻译
- 📝 实时翻译:输入即时翻译
- 📚 历史记录:自动保存翻译历史
- ⭐ 收藏管理:收藏常用翻译
- 📖 常用短语:分类常用短语库
- 🔊 语音朗读:文本朗读功能(预留)
- 📋 快速复制:一键复制翻译结果
- 💾 数据持久化:使用SharedPreferences
技术栈
- Flutter 3.6+
- Dart 3.0+
- shared_preferences: 数据持久化
- Material Design 3
项目架构
中英互译助手
翻译页面
历史记录
常用短语
收藏管理
语言切换
翻译引擎
结果展示
记录列表
收藏操作
分类浏览
音标显示
数据模型设计
TranslationRecord - 翻译记录模型
dart
class TranslationRecord {
final String id; // 唯一标识
final String sourceText; // 原文
final String translatedText; // 译文
final String sourceLanguage; // 源语言
final String targetLanguage; // 目标语言
final DateTime timestamp; // 时间戳
bool isFavorite; // 是否收藏
TranslationRecord({
required this.id,
required this.sourceText,
required this.translatedText,
required this.sourceLanguage,
required this.targetLanguage,
required this.timestamp,
this.isFavorite = false,
});
// JSON序列化
Map<String, dynamic> toJson() {
return {
'id': id,
'sourceText': sourceText,
'translatedText': translatedText,
'sourceLanguage': sourceLanguage,
'targetLanguage': targetLanguage,
'timestamp': timestamp.toIso8601String(),
'isFavorite': isFavorite,
};
}
// JSON反序列化
factory TranslationRecord.fromJson(Map<String, dynamic> json) {
return TranslationRecord(
id: json['id'],
sourceText: json['sourceText'],
translatedText: json['translatedText'],
sourceLanguage: json['sourceLanguage'],
targetLanguage: json['targetLanguage'],
timestamp: DateTime.parse(json['timestamp']),
isFavorite: json['isFavorite'] ?? false,
);
}
}
CommonPhrase - 常用短语模型
dart
class CommonPhrase {
final String chinese; // 中文
final String english; // 英文
final String category; // 分类
final String pronunciation; // 音标
CommonPhrase({
required this.chinese,
required this.english,
required this.category,
required this.pronunciation,
});
}
核心功能实现
1. 语言切换功能
实现中英文双向切换:
dart
bool _isChineseToEnglish = true;
void _swapLanguages() {
setState(() {
_isChineseToEnglish = !_isChineseToEnglish;
// 交换输入和输出
final temp = _inputController.text;
_inputController.text = _translatedText;
_translatedText = temp;
});
}
// UI展示
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
_isChineseToEnglish ? '中文' : '英文',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(width: 16),
IconButton(
icon: Icon(Icons.swap_horiz, size: 32),
onPressed: _swapLanguages,
color: Colors.blue,
),
SizedBox(width: 16),
Text(
_isChineseToEnglish ? '英文' : '中文',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
)
切换特点:
- 一键切换方向
- 自动交换内容
- 视觉反馈清晰
2. 翻译引擎实现
使用本地词典实现翻译:
dart
// 翻译词典
final Map<String, String> _chineseToEnglish = {
'你好': 'Hello',
'谢谢': 'Thank you',
'再见': 'Goodbye',
// ... 更多词汇
};
// 中译英
String _translateChineseToEnglish(String text) {
for (var entry in _chineseToEnglish.entries) {
if (text.contains(entry.key)) {
return text.replaceAll(entry.key, entry.value);
}
}
// 找不到时的处理
return 'Translation: ${text.split('').join(' ')}';
}
// 英译中
String _translateEnglishToChinese(String text) {
final lowerText = text.toLowerCase();
for (var entry in _chineseToEnglish.entries) {
if (lowerText.contains(entry.value.toLowerCase())) {
return text.replaceAll(
RegExp(entry.value, caseSensitive: false),
entry.key,
);
}
}
return '翻译:${text.split(' ').join('·')}';
}
// 执行翻译
Future<void> _translate() async {
if (_inputController.text.trim().isEmpty) return;
setState(() {
_isTranslating = true;
});
// 模拟翻译延迟
await Future.delayed(const Duration(milliseconds: 500));
String result;
if (_isChineseToEnglish) {
result = _translateChineseToEnglish(_inputController.text);
} else {
result = _translateEnglishToChinese(_inputController.text);
}
setState(() {
_translatedText = result;
_isTranslating = false;
});
// 添加到历史记录
_addToHistory(result);
}
翻译特点:
- 本地词典查找
- 支持部分匹配
- 异步处理
- 加载状态提示
3. 输入区域设计
创建美观的输入框:
dart
Container(
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withValues(alpha: 0.2),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题栏
Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
Icon(Icons.edit, size: 20, color: Colors.grey.shade600),
SizedBox(width: 8),
Text(
'输入文本',
style: TextStyle(fontSize: 14, color: Colors.grey.shade600),
),
],
),
),
// 输入框
TextField(
controller: _inputController,
maxLines: 6,
decoration: InputDecoration(
hintText: '请输入要翻译的内容...',
border: InputBorder.none,
contentPadding: EdgeInsets.all(16),
),
style: TextStyle(fontSize: 16),
),
// 字符统计
Padding(
padding: const EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (_inputController.text.isNotEmpty)
Text(
'${_inputController.text.length} 字符',
style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
),
],
),
),
],
),
)
输入框特点:
- 卡片式设计
- 阴影效果
- 字符计数
- 多行输入
4. 翻译结果展示
美观的结果展示区域:
dart
if (_translatedText.isNotEmpty)
Container(
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.green.shade50,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.green.shade200),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题栏
Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
Icon(Icons.check_circle, size: 20, color: Colors.green.shade700),
SizedBox(width: 8),
Text(
'翻译结果',
style: TextStyle(
fontSize: 14,
color: Colors.green.shade700,
fontWeight: FontWeight.bold,
),
),
],
),
),
// 翻译文本
Padding(
padding: const EdgeInsets.all(16),
child: SelectableText(
_translatedText,
style: TextStyle(fontSize: 16, height: 1.5),
),
),
// 操作按钮
Padding(
padding: const EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton.icon(
icon: Icon(Icons.copy, size: 18),
label: Text('复制'),
onPressed: () => _copyToClipboard(_translatedText),
),
SizedBox(width: 8),
TextButton.icon(
icon: Icon(Icons.volume_up, size: 18),
label: Text('朗读'),
onPressed: _speakText,
),
],
),
),
],
),
)
结果展示特点:
- 绿色主题
- 可选择文本
- 快捷操作
- 清晰布局
5. 历史记录管理
实现翻译历史的保存和展示:
dart
List<TranslationRecord> historyRecords = [];
// 添加记录
void _addRecord(TranslationRecord record) {
setState(() {
historyRecords.insert(0, record);
// 限制历史记录数量
if (historyRecords.length > 100) {
historyRecords.removeLast();
}
});
_saveData();
}
// 保存数据
Future<void> _saveData() async {
final prefs = await SharedPreferences.getInstance();
final historyData = historyRecords.map((r) => jsonEncode(r.toJson())).toList();
await prefs.setStringList('translation_history', historyData);
}
// 加载数据
Future<void> _loadData() async {
final prefs = await SharedPreferences.getInstance();
final historyData = prefs.getStringList('translation_history') ?? [];
setState(() {
historyRecords = historyData
.map((json) => TranslationRecord.fromJson(jsonDecode(json)))
.toList();
});
}
// 清空历史
void _clearHistory() {
setState(() {
historyRecords.clear();
});
_saveData();
}
历史记录特点:
- 自动保存
- 限制数量
- 持久化存储
- 批量清空
6. 历史记录卡片
展示历史记录的卡片设计:
dart
Widget _buildHistoryCard(BuildContext context, TranslationRecord record) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 语言标签和时间
Row(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Text(
'${record.sourceLanguage} → ${record.targetLanguage}',
style: TextStyle(fontSize: 12, color: Colors.blue),
),
),
Spacer(),
Text(
_formatTime(record.timestamp),
style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
),
],
),
SizedBox(height: 12),
// 原文
Text(
record.sourceText,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
SizedBox(height: 8),
// 译文
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Text(
record.translatedText,
style: TextStyle(fontSize: 14, color: Colors.grey.shade800),
),
),
SizedBox(height: 8),
// 操作按钮
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
icon: Icon(
record.isFavorite ? Icons.star : Icons.star_border,
color: record.isFavorite ? Colors.amber : Colors.grey,
),
onPressed: () => onToggleFavorite(record),
),
IconButton(
icon: Icon(Icons.copy, size: 20),
onPressed: () => _copyText(record.translatedText),
),
IconButton(
icon: Icon(Icons.delete, size: 20),
onPressed: () => onDelete(record),
),
],
),
],
),
),
);
}
// 时间格式化
String _formatTime(DateTime time) {
final now = DateTime.now();
final diff = now.difference(time);
if (diff.inMinutes < 1) return '刚刚';
if (diff.inHours < 1) return '${diff.inMinutes}分钟前';
if (diff.inDays < 1) return '${diff.inHours}小时前';
if (diff.inDays < 7) return '${diff.inDays}天前';
return '${time.month}-${time.day}';
}
卡片特点:
- 语言方向标签
- 相对时间显示
- 快捷操作按钮
- 收藏状态显示
7. 常用短语功能
分类展示常用短语:
dart
class _CommonPhrasesPageState extends State<CommonPhrasesPage> {
String _selectedCategory = '问候';
final Map<String, List<CommonPhrase>> _phrases = {
'问候': [
CommonPhrase(
chinese: '你好',
english: 'Hello',
category: '问候',
pronunciation: 'həˈləʊ',
),
// ... 更多短语
],
'感谢': [
CommonPhrase(
chinese: '谢谢',
english: 'Thank you',
category: '感谢',
pronunciation: 'θæŋk juː',
),
// ... 更多短语
],
// ... 更多分类
};
@override
Widget build(BuildContext context) {
return Row(
children: [
// 左侧分类列表
Container(
width: 100,
color: Colors.grey.shade100,
child: ListView.builder(
itemCount: categories.length,
itemBuilder: (context, index) {
final category = categories[index];
final isSelected = category == _selectedCategory;
return InkWell(
onTap: () {
setState(() {
_selectedCategory = category;
});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
color: isSelected ? Colors.white : Colors.transparent,
border: Border(
left: BorderSide(
color: isSelected ? Colors.blue : Colors.transparent,
width: 3,
),
),
),
child: Center(
child: Text(
category,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
color: isSelected ? Colors.blue : Colors.black87,
),
),
),
),
);
},
),
),
// 右侧短语列表
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(16),
itemCount: currentPhrases.length,
itemBuilder: (context, index) {
return _buildPhraseCard(currentPhrases[index]);
},
),
),
],
);
}
}
常用短语特点:
- 分类浏览
- 左右布局
- 音标显示
- 朗读功能
8. 短语卡片设计
展示短语的详细信息:
dart
Widget _buildPhraseCard(CommonPhrase phrase) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 中文
Text(
phrase.chinese,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
// 英文
Text(
phrase.english,
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade700,
),
),
],
),
),
// 朗读按钮
IconButton(
icon: Icon(Icons.volume_up),
onPressed: () => _speakPhrase(phrase),
),
],
),
SizedBox(height: 8),
// 音标
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16),
),
child: Text(
'/${phrase.pronunciation}/',
style: TextStyle(
fontSize: 12,
color: Colors.blue,
fontStyle: FontStyle.italic,
),
),
),
],
),
),
);
}
短语卡片特点:
- 中英对照
- 音标展示
- 朗读按钮
- 清晰布局
9. 收藏功能
管理收藏的翻译:
dart
List<TranslationRecord> favoriteRecords = [];
void _toggleFavorite(TranslationRecord record) {
setState(() {
record.isFavorite = !record.isFavorite;
if (record.isFavorite) {
if (!favoriteRecords.any((r) => r.id == record.id)) {
favoriteRecords.insert(0, record);
}
} else {
favoriteRecords.removeWhere((r) => r.id == record.id);
}
});
_saveData();
}
// 收藏页面
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('我的收藏')),
body: favoriteRecords.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star_outline, size: 80, color: Colors.grey.shade400),
SizedBox(height: 16),
Text('还没有收藏的翻译'),
],
),
)
: ListView.builder(
itemCount: favoriteRecords.length,
itemBuilder: (context, index) {
return _buildFavoriteCard(favoriteRecords[index]);
},
),
);
}
收藏特点:
- 一键收藏
- 独立列表
- 快速访问
- 持久化保存
UI组件设计
1. 翻译按钮
大号翻译按钮设计:
dart
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: _isTranslating ? null : _translate,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
child: _isTranslating
? SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.translate),
SizedBox(width: 8),
Text('翻译', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
],
),
),
)
2. 语言标签
小型语言标签:
dart
Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Text(
'中文 → 英文',
style: TextStyle(fontSize: 12, color: Colors.blue),
),
)
3. 操作按钮组
快捷操作按钮:
dart
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton.icon(
icon: Icon(Icons.copy, size: 18),
label: Text('复制'),
onPressed: _copyText,
),
SizedBox(width: 8),
TextButton.icon(
icon: Icon(Icons.volume_up, size: 18),
label: Text('朗读'),
onPressed: _speakText,
),
],
)
4. 底部导航栏
Material 3风格导航:
dart
NavigationBar(
selectedIndex: _selectedIndex,
onDestinationSelected: (index) {
setState(() {
_selectedIndex = index;
});
},
destinations: const [
NavigationDestination(
icon: Icon(Icons.translate_outlined),
selectedIcon: Icon(Icons.translate),
label: '翻译',
),
NavigationDestination(
icon: Icon(Icons.history_outlined),
selectedIcon: Icon(Icons.history),
label: '历史',
),
NavigationDestination(
icon: Icon(Icons.book_outlined),
selectedIcon: Icon(Icons.book),
label: '常用语',
),
NavigationDestination(
icon: Icon(Icons.star_outline),
selectedIcon: Icon(Icons.star),
label: '收藏',
),
],
)
功能扩展建议
1. 在线翻译API集成
接入真实翻译API:
dart
import 'package:http/http.dart' as http;
class TranslationApiService {
static const String apiKey = 'YOUR_API_KEY';
static const String baseUrl = 'https://translation.googleapis.com/language/translate/v2';
Future<String> translate(String text, String sourceLang, String targetLang) async {
final response = await http.post(
Uri.parse(baseUrl),
headers: {
'Content-Type': 'application/json',
},
body: jsonEncode({
'q': text,
'source': sourceLang,
'target': targetLang,
'format': 'text',
'key': apiKey,
}),
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return data['data']['translations'][0]['translatedText'];
}
throw Exception('Translation failed');
}
}
2. 语音朗读功能
使用flutter_tts实现语音朗读:
dart
import 'package:flutter_tts/flutter_tts.dart';
class TextToSpeechService {
final FlutterTts _tts = FlutterTts();
Future<void> init() async {
await _tts.setLanguage('en-US');
await _tts.setSpeechRate(0.5);
await _tts.setVolume(1.0);
await _tts.setPitch(1.0);
}
Future<void> speak(String text, String language) async {
await _tts.setLanguage(language == '中文' ? 'zh-CN' : 'en-US');
await _tts.speak(text);
}
Future<void> stop() async {
await _tts.stop();
}
}
// 使用
IconButton(
icon: Icon(Icons.volume_up),
onPressed: () async {
final tts = TextToSpeechService();
await tts.init();
await tts.speak(_translatedText, '英文');
},
)
3. 语音输入功能
使用speech_to_text实现语音输入:
dart
import 'package:speech_to_text/speech_to_text.dart';
class SpeechToTextService {
final SpeechToText _speech = SpeechToText();
bool _isListening = false;
Future<void> init() async {
await _speech.initialize();
}
Future<void> startListening(Function(String) onResult) async {
if (!_isListening) {
_isListening = true;
await _speech.listen(
onResult: (result) {
onResult(result.recognizedWords);
},
);
}
}
Future<void> stopListening() async {
if (_isListening) {
_isListening = false;
await _speech.stop();
}
}
}
// 添加语音输入按钮
IconButton(
icon: Icon(_isListening ? Icons.mic : Icons.mic_none),
onPressed: () async {
if (_isListening) {
await _speechService.stopListening();
} else {
await _speechService.startListening((text) {
setState(() {
_inputController.text = text;
});
});
}
},
)
4. 拍照翻译功能
使用相机识别文字并翻译:
dart
import 'package:image_picker/image_picker.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
class OCRTranslationService {
final ImagePicker _picker = ImagePicker();
final TextRecognizer _textRecognizer = GoogleMlKit.vision.textRecognizer();
Future<String> recognizeTextFromCamera() async {
final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
if (photo == null) return '';
final inputImage = InputImage.fromFilePath(photo.path);
final RecognizedText recognizedText = await _textRecognizer.processImage(inputImage);
return recognizedText.text;
}
Future<String> recognizeTextFromGallery() async {
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image == null) return '';
final inputImage = InputImage.fromFilePath(image.path);
final RecognizedText recognizedText = await _textRecognizer.processImage(inputImage);
return recognizedText.text;
}
}
// 添加拍照按钮
Row(
children: [
IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () async {
final text = await _ocrService.recognizeTextFromCamera();
setState(() {
_inputController.text = text;
});
},
tooltip: '拍照翻译',
),
IconButton(
icon: Icon(Icons.photo_library),
onPressed: () async {
final text = await _ocrService.recognizeTextFromGallery();
setState(() {
_inputController.text = text;
});
},
tooltip: '相册翻译',
),
],
)
5. 离线词典
实现完整的离线词典:
dart
import 'package:sqflite/sqflite.dart';
class OfflineDictionary {
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
String path = join(await getDatabasesPath(), 'dictionary.db');
return await openDatabase(
path,
version: 1,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE words(
id INTEGER PRIMARY KEY AUTOINCREMENT,
english TEXT,
chinese TEXT,
pronunciation TEXT,
category TEXT,
example TEXT
)
''');
},
);
}
Future<String?> translate(String word) async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query(
'words',
where: 'english = ? OR chinese = ?',
whereArgs: [word, word],
);
if (maps.isNotEmpty) {
return maps[0]['english'] == word
? maps[0]['chinese']
: maps[0]['english'];
}
return null;
}
Future<void> importDictionary(List<Map<String, String>> words) async {
final db = await database;
final batch = db.batch();
for (var word in words) {
batch.insert('words', word);
}
await batch.commit();
}
}
6. 翻译历史统计
统计翻译使用情况:
dart
class TranslationStatistics {
final List<TranslationRecord> records;
TranslationStatistics(this.records);
// 总翻译次数
int get totalTranslations => records.length;
// 今日翻译次数
int get todayTranslations {
final today = DateTime.now();
return records.where((r) {
return r.timestamp.year == today.year &&
r.timestamp.month == today.month &&
r.timestamp.day == today.day;
}).length;
}
// 最常用的翻译方向
String get mostUsedDirection {
final directions = <String, int>{};
for (var record in records) {
final key = '${record.sourceLanguage} → ${record.targetLanguage}';
directions[key] = (directions[key] ?? 0) + 1;
}
return directions.entries
.reduce((a, b) => a.value > b.value ? a : b)
.key;
}
// 最常翻译的词汇
List<String> get topWords {
final wordCount = <String, int>{};
for (var record in records) {
wordCount[record.sourceText] = (wordCount[record.sourceText] ?? 0) + 1;
}
final sorted = wordCount.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
return sorted.take(10).map((e) => e.key).toList();
}
Widget buildStatisticsCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('翻译统计', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 16),
_buildStatItem('总翻译次数', '$totalTranslations 次'),
_buildStatItem('今日翻译', '$todayTranslations 次'),
_buildStatItem('常用方向', mostUsedDirection),
],
),
),
);
}
}
7. 多语言支持
扩展支持更多语言:
dart
enum Language {
chinese('中文', 'zh'),
english('英文', 'en'),
japanese('日文', 'ja'),
korean('韩文', 'ko'),
french('法文', 'fr'),
german('德文', 'de'),
spanish('西班牙文', 'es');
final String label;
final String code;
const Language(this.label, this.code);
}
class MultiLanguageTranslator extends StatefulWidget {
@override
State<MultiLanguageTranslator> createState() => _MultiLanguageTranslatorState();
}
class _MultiLanguageTranslatorState extends State<MultiLanguageTranslator> {
Language _sourceLanguage = Language.chinese;
Language _targetLanguage = Language.english;
Widget _buildLanguageSelector() {
return Row(
children: [
Expanded(
child: DropdownButton<Language>(
value: _sourceLanguage,
isExpanded: true,
items: Language.values.map((lang) {
return DropdownMenuItem(
value: lang,
child: Text(lang.label),
);
}).toList(),
onChanged: (value) {
setState(() {
_sourceLanguage = value!;
});
},
),
),
IconButton(
icon: Icon(Icons.swap_horiz),
onPressed: () {
setState(() {
final temp = _sourceLanguage;
_sourceLanguage = _targetLanguage;
_targetLanguage = temp;
});
},
),
Expanded(
child: DropdownButton<Language>(
value: _targetLanguage,
isExpanded: true,
items: Language.values.map((lang) {
return DropdownMenuItem(
value: lang,
child: Text(lang.label),
);
}).toList(),
onChanged: (value) {
setState(() {
_targetLanguage = value!;
});
},
),
),
],
);
}
}
8. 单词本功能
创建个人单词本:
dart
class Vocabulary {
final String word;
final String translation;
final String pronunciation;
final String example;
final DateTime addedDate;
int reviewCount;
DateTime? lastReviewDate;
Vocabulary({
required this.word,
required this.translation,
required this.pronunciation,
required this.example,
required this.addedDate,
this.reviewCount = 0,
this.lastReviewDate,
});
}
class VocabularyBook extends StatefulWidget {
@override
State<VocabularyBook> createState() => _VocabularyBookState();
}
class _VocabularyBookState extends State<VocabularyBook> {
List<Vocabulary> _vocabularies = [];
void _addToVocabulary(String word, String translation) {
setState(() {
_vocabularies.add(Vocabulary(
word: word,
translation: translation,
pronunciation: '',
example: '',
addedDate: DateTime.now(),
));
});
_saveVocabularies();
}
Widget _buildVocabularyCard(Vocabulary vocab) {
return Card(
child: ListTile(
title: Text(vocab.word),
subtitle: Text(vocab.translation),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text('复习${vocab.reviewCount}次'),
IconButton(
icon: Icon(Icons.check),
onPressed: () => _markAsReviewed(vocab),
),
],
),
),
);
}
void _markAsReviewed(Vocabulary vocab) {
setState(() {
vocab.reviewCount++;
vocab.lastReviewDate = DateTime.now();
});
_saveVocabularies();
}
}
9. 翻译分享功能
分享翻译结果:
dart
import 'package:share_plus/share_plus.dart';
class TranslationShareService {
Future<void> shareTranslation(TranslationRecord record) async {
final text = '''
【翻译】
原文:${record.sourceText}
译文:${record.translatedText}
${record.sourceLanguage} → ${record.targetLanguage}
来自中英互译助手
''';
await Share.share(text);
}
Future<void> shareAsImage(TranslationRecord record) async {
// 生成翻译卡片图片
final image = await _generateTranslationCard(record);
await Share.shareXFiles([XFile(image.path)]);
}
}
// 添加分享按钮
IconButton(
icon: Icon(Icons.share),
onPressed: () async {
await TranslationShareService().shareTranslation(record);
},
tooltip: '分享',
)
10. 翻译质量评分
评估翻译质量:
dart
class TranslationQuality {
// 简单的质量评分算法
static double calculateScore(String source, String translation) {
double score = 100.0;
// 长度检查
if (translation.isEmpty) return 0;
// 长度比例检查
final lengthRatio = translation.length / source.length;
if (lengthRatio < 0.5 || lengthRatio > 2.0) {
score -= 20;
}
// 特殊字符检查
if (translation.contains('?') || translation.contains('Unknown')) {
score -= 30;
}
return score.clamp(0, 100);
}
static String getQualityLabel(double score) {
if (score >= 80) return '优秀';
if (score >= 60) return '良好';
if (score >= 40) return '一般';
return '较差';
}
Widget buildQualityIndicator(double score) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: _getQualityColor(score).withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(16),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
_getQualityIcon(score),
size: 16,
color: _getQualityColor(score),
),
SizedBox(width: 4),
Text(
getQualityLabel(score),
style: TextStyle(
fontSize: 12,
color: _getQualityColor(score),
),
),
],
),
);
}
Color _getQualityColor(double score) {
if (score >= 80) return Colors.green;
if (score >= 60) return Colors.blue;
if (score >= 40) return Colors.orange;
return Colors.red;
}
IconData _getQualityIcon(double score) {
if (score >= 80) return Icons.check_circle;
if (score >= 60) return Icons.thumb_up;
if (score >= 40) return Icons.warning;
return Icons.error;
}
}
性能优化建议
1. 翻译缓存
缓存翻译结果避免重复翻译:
dart
class TranslationCache {
static final Map<String, String> _cache = {};
static String? get(String text, String direction) {
final key = '$text|$direction';
return _cache[key];
}
static void set(String text, String direction, String translation) {
final key = '$text|$direction';
_cache[key] = translation;
// 限制缓存大小
if (_cache.length > 1000) {
_cache.remove(_cache.keys.first);
}
}
static void clear() {
_cache.clear();
}
}
// 使用缓存
Future<String> _translateWithCache(String text) async {
final direction = _isChineseToEnglish ? 'zh-en' : 'en-zh';
// 检查缓存
final cached = TranslationCache.get(text, direction);
if (cached != null) {
return cached;
}
// 执行翻译
final result = await _translate(text);
// 保存到缓存
TranslationCache.set(text, direction, result);
return result;
}
2. 防抖处理
避免频繁触发翻译:
dart
import 'dart:async';
class Debouncer {
final Duration delay;
Timer? _timer;
Debouncer({this.delay = const Duration(milliseconds: 500)});
void run(VoidCallback action) {
_timer?.cancel();
_timer = Timer(delay, action);
}
void dispose() {
_timer?.cancel();
}
}
// 使用防抖
final _debouncer = Debouncer();
TextField(
onChanged: (value) {
_debouncer.run(() {
_translate();
});
},
)
3. 历史记录分页
分页加载历史记录:
dart
class PaginatedHistory extends StatefulWidget {
@override
State<PaginatedHistory> createState() => _PaginatedHistoryState();
}
class _PaginatedHistoryState extends State<PaginatedHistory> {
final ScrollController _scrollController = ScrollController();
List<TranslationRecord> _displayedRecords = [];
int _currentPage = 0;
final int _pageSize = 20;
bool _isLoading = false;
@override
void initState() {
super.initState();
_loadMore();
_scrollController.addListener(_onScroll);
}
void _onScroll() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent * 0.8) {
_loadMore();
}
}
Future<void> _loadMore() async {
if (_isLoading) return;
setState(() {
_isLoading = true;
});
final start = _currentPage * _pageSize;
final end = min(start + _pageSize, allRecords.length);
setState(() {
_displayedRecords.addAll(allRecords.sublist(start, end));
_currentPage++;
_isLoading = false;
});
}
}
测试建议
1. 单元测试
测试翻译逻辑:
dart
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Translation Tests', () {
test('Chinese to English translation', () {
final translator = Translator();
final result = translator.translate('你好', 'zh', 'en');
expect(result, 'Hello');
});
test('Translation cache', () {
TranslationCache.set('你好', 'zh-en', 'Hello');
final cached = TranslationCache.get('你好', 'zh-en');
expect(cached, 'Hello');
});
});
}
2. Widget测试
测试UI组件:
dart
void main() {
testWidgets('Translation button works', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(home: TranslatePage()));
// 输入文本
await tester.enterText(find.byType(TextField), '你好');
// 点击翻译按钮
await tester.tap(find.text('翻译'));
await tester.pumpAndSettle();
// 验证结果
expect(find.text('Hello'), findsOneWidget);
});
}
部署发布
1. Android打包
bash
flutter build apk --release
flutter build appbundle --release
2. iOS打包
bash
flutter build ipa --release
3. 应用图标
yaml
dev_dependencies:
flutter_launcher_icons: ^0.13.1
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/icon/app_icon.png"
项目总结
技术亮点
- 双向翻译:支持中英文互译
- 本地词典:无需网络即可翻译
- 历史管理:自动保存翻译记录
- 常用短语:分类短语库
- 收藏功能:快速访问常用翻译
- 精美UI:卡片式设计、清晰布局
- 数据持久化:SharedPreferences保存数据
学习收获
通过本项目,你将掌握:
- Flutter文本处理
- 数据模型设计
- SharedPreferences使用
- 列表展示和管理
- 时间格式化
- 剪贴板操作
- 状态管理
- UI组件设计
应用场景
本应用适用于:
- 日常翻译需求
- 语言学习辅助
- 旅游出行翻译
- 商务沟通
后续优化方向
- 接入在线翻译API
- 添加语音朗读功能
- 实现语音输入
- 支持拍照翻译
- 完善离线词典
- 添加翻译统计
- 支持多语言
- 创建单词本
- 实现分享功能
- 翻译质量评分
这个中英互译助手应用展示了Flutter在工具类应用开发中的实用性。通过简洁的界面和完善的功能,为用户提供了便捷的翻译体验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net