Files
kuaishai2/lib/features/settings/widgets/language_panel.dart
Developer 3d849bd468 feat(i18n): 完成全量 UI 文本国际化,替换所有硬编码中文为 AppLocalizations 调用
- core/localization: 新增约 60 个翻译键(含参数化方法),中英双语覆盖
- shared/widgets: CommonDialog 默认参数国际化
- features/home: 完成页操作步骤指引、状态栏串口连接状态、程序列表状态标签
- features/programs: 表头状态列、表单验证提示、导入/模板操作反馈、删除确认(参数化)
- features/program_detail: 步骤列表/表单标题、删除确认、速度档位显示(参数化)
- features/device: run_state_provider 错误消息改为错误码
- features/settings: 升级页、密码面板、语言面板、U盘导入面板、串口配置面板全部替换

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 15:09:47 +08:00

136 lines
3.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/localization/app_localizations.dart';
import '../../../core/localization/locale_provider.dart';
import '../../../core/theme/app_theme.dart';
/// 语言设置面板
///
/// 在设置页右侧主区域渲染语言切换控件,直接调用
/// [LocaleNotifier] 修改全局 locale。
class LanguagePanel extends ConsumerWidget {
const LanguagePanel({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final locale = ref.watch(localeProvider);
final currentLang = locale.languageCode;
return ListView(
padding: EdgeInsets.zero,
children: [
_SectionCard(
title: l10n?.languageSettings ?? '语言设置',
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_langTile(
context: context,
ref: ref,
value: 'zh',
groupValue: currentLang,
label: '简体中文',
),
const Divider(height: 1),
_langTile(
context: context,
ref: ref,
value: 'en',
groupValue: currentLang,
label: 'English',
),
],
),
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Text(
l10n?.switchLanguageEffect ?? '切换语言后立即生效',
style: TextStyle(color: AppTheme.textSecondary, fontSize: 12),
),
),
],
);
}
Widget _langTile({
required BuildContext context,
required WidgetRef ref,
required String value,
required String groupValue,
required String label,
}) {
final selected = value == groupValue;
return InkWell(
onTap: () {
if (value == 'zh') {
ref.read(localeProvider.notifier).setChinese();
} else {
ref.read(localeProvider.notifier).setEnglish();
}
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
child: Row(
children: [
Icon(
selected ? Icons.radio_button_checked : Icons.radio_button_off,
color: selected ? AppTheme.primaryColor : AppTheme.idleColor,
size: 20,
),
const SizedBox(width: 12),
Expanded(
child: Text(
label,
style: TextStyle(
color: AppTheme.textPrimary,
fontWeight: selected ? FontWeight.w600 : FontWeight.normal,
),
),
),
if (selected)
Icon(Icons.check_circle, color: AppTheme.successColor, size: 18),
],
),
),
);
}
}
class _SectionCard extends StatelessWidget {
final String title;
final Widget child;
const _SectionCard({required this.title, required this.child});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppTheme.borderSubtle),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
title,
style: TextStyle(
color: AppTheme.textPrimary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const Divider(),
child,
],
),
);
}
}