zeba_academy_localization 1.0.0
zeba_academy_localization: ^1.0.0 copied to clipboard
Smart offline localization and accessibility Flutter package
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:zeba_academy_localization/zeba_academy_localization.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Zeba Smart Localization',
themeMode: ThemeMode.system,
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en', 'US'),
Locale('hi', 'IN'),
Locale('es', 'ES'),
],
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TTSHelper _tts = TTSHelper();
final VoiceInputHelper _voice = VoiceInputHelper();
String _spokenText = "Tap the mic and speak";
String _translatedText = "";
bool _listening = false;
@override
void initState() {
super.initState();
_voice.init();
}
@override
Widget build(BuildContext context) {
Locale locale = LocaleHelper.getDeviceLocale(context);
return Scaffold(
appBar: AppBar(
title: const Text("Zeba Smart Localization"),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
const SizedBox(height: 10),
/// Locale Info
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.language),
const SizedBox(width: 10),
Text(
"Detected Locale: ${locale.languageCode}",
style: const TextStyle(fontSize: 16),
),
],
),
),
const SizedBox(height: 30),
/// Spoken Text Card
_buildCard(
title: "Spoken Text",
text: _spokenText,
icon: Icons.mic,
color: Colors.orange,
),
const SizedBox(height: 20),
/// Translated Text Card
_buildCard(
title: "Translated Text",
text: _translatedText.isEmpty
? "Translation will appear here"
: _translatedText,
icon: Icons.translate,
color: Colors.green,
),
const Spacer(),
/// Mic Button
GestureDetector(
onTap: () async {
setState(() {
_listening = true;
});
String? result = await _voice.listen();
setState(() {
_listening = false;
});
if (result != null && result.isNotEmpty) {
setState(() {
_spokenText = result;
_translatedText =
OfflineTranslation.translate(result, locale);
});
await _tts.speak(
_translatedText,
languageCode: locale.languageCode,
);
}
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: _listening ? 90 : 80,
width: _listening ? 90 : 80,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _listening ? Colors.red : Colors.blue,
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.2),
blurRadius: 10,
)
],
),
child: const Icon(
Icons.mic,
size: 40,
color: Colors.white,
),
),
),
const SizedBox(height: 20),
Text(
_listening
? "Listening..."
: "Tap the microphone and speak",
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
const SizedBox(height: 20),
],
),
),
);
}
Widget _buildCard({
required String title,
required String text,
required IconData icon,
required Color color,
}) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(18),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.08),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: color.withValues(alpha: 0.3),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, color: color),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
color: color,
),
),
const SizedBox(height: 6),
Text(
text,
style: const TextStyle(fontSize: 16),
),
],
),
),
],
),
);
}
}