auto_translate_plugin 1.1.0
auto_translate_plugin: ^1.1.0 copied to clipboard
A premium Flutter plugin for seamless on-device text translation using Google ML Kit. Offline, privacy-first, and easy to integrate.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:auto_translate_plugin/auto_translate_plugin.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => TranslatorProvider(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Auto Translate Demo',
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.indigo,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
static const Map<String, String> languages = {
'en': 'English',
'ta': 'தமிழ் (Tamil)',
'hi': 'हिंदी (Hindi)',
'te': 'తెలుగు (Telugu)',
'ml': 'മലയാളം (Malayalam)',
'kn': 'ಕನ್ನಡ (Kannada)',
'mr': 'मराठी (Marathi)',
'gu': 'ગુજરાતી (Gujarati)',
'bn': 'বাংলা (Bengali)',
'ur': 'اردو (Urdu)',
'pa': 'ਪੰਜਾਬੀ (Punjabi)',
'fr': 'Français (French)',
'de': 'Deutsch (German)',
'es': 'Español (Spanish)',
'it': 'Italiano (Italian)',
'ar': 'العربية (Arabic)',
'zh': '中文 (Chinese)',
'ja': '日本語 (Japanese)',
'ko': '한국어 (Korean)',
'ru': 'Русский (Russian)',
'pt': 'Português (Portuguese)',
'tr': 'Türkçe (Turkish)',
'vi': 'Tiếng Việt (Vietnamese)',
'th': 'ไทย (Thai)',
'id': 'Bahasa Indonesia',
'ms': 'Bahasa Melayu',
'nl': 'Nederlands (Dutch)',
'pl': 'Polski (Polish)',
'sv': 'Svenska (Swedish)',
'da': 'Dansk (Danish)',
'fi': 'Suomi (Finnish)',
'no': 'Norsk (Norwegian)',
'el': 'Ελληνικά (Greek)',
'he': 'עברית (Hebrew)',
'ro': 'Română (Romanian)',
'hu': 'Magyar (Hungarian)',
'cs': 'Čeština (Czech)',
'sk': 'Slovenčina (Slovak)',
'uk': 'Українська (Ukrainian)',
};
@override
Widget build(BuildContext context) {
final translator = context.read<TranslatorProvider>();
final currentLang = context.watch<TranslatorProvider>().languageCode;
return Scaffold(
appBar: AppBar(
title: const AutoTranslateText(
"Premium Auto Translate",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22),
),
centerTitle: true,
elevation: 4,
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeaderCard(context),
const SizedBox(height: 30),
_buildSectionTitle("Quick Selection (ML Kit)"),
const SizedBox(height: 15),
_buildQuickGrid(context, translator, currentLang),
const SizedBox(height: 30),
_buildSectionTitle("All Languages (130+ via Cloud)"),
const SizedBox(height: 15),
_buildLanguagePicker(context, translator, currentLang),
const SizedBox(height: 40),
const Center(
child: AutoTranslateText(
"Experience the world in your language",
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.grey,
fontSize: 14,
),
),
),
],
),
),
);
}
Widget _buildHeaderCard(BuildContext context) {
return Card(
elevation: 8,
shadowColor: Theme.of(context).colorScheme.primary.withAlpha(50),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(
colors: [
Theme.of(context).colorScheme.primaryContainer,
Theme.of(context).colorScheme.surface,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
padding: const EdgeInsets.all(24),
child: const Column(
children: [
AutoTranslateText(
"Welcome to a Borderless World!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.w900,
letterSpacing: -0.5,
),
),
SizedBox(height: 16),
AutoTranslateText(
"Select any language below to see the magic. Every title, button, and description will translate instantly using our hybrid ML engine.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
height: 1.5,
color: Colors.black87,
),
),
],
),
),
);
}
Widget _buildSectionTitle(String title) {
return Row(
children: [
Container(
width: 4,
height: 24,
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 10),
Text(
title,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
);
}
Widget _buildQuickGrid(
BuildContext context,
TranslatorProvider provider,
String currentCode,
) {
final quickLangs = ['en', 'ta', 'hi', 'te', 'ml', 'kn'];
return GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 2.2,
children: quickLangs.map((code) {
return _languageButton(
context,
provider,
currentCode,
languages[code]!.split(' ')[0],
code,
);
}).toList(),
);
}
Widget _buildLanguagePicker(
BuildContext context,
TranslatorProvider provider,
String currentCode,
) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer.withAlpha(80),
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Theme.of(context).dividerColor),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
value: languages.containsKey(currentCode) ? currentCode : 'en',
items: languages.entries.map((e) {
return DropdownMenuItem(
value: e.key,
child: Text(e.value, style: const TextStyle(fontSize: 16)),
);
}).toList(),
onChanged: (val) {
if (val != null) provider.changeLanguage(val);
},
),
),
);
}
Widget _languageButton(
BuildContext context,
TranslatorProvider provider,
String currentCode,
String label,
String code,
) {
final isSelected = currentCode == code;
return ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: isSelected ? 4 : 0,
backgroundColor: isSelected
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.surface,
foregroundColor: isSelected
? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onSurface,
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: isSelected
? BorderSide.none
: const BorderSide(color: Colors.grey),
),
),
onPressed: () => provider.changeLanguage(code),
child: Text(label, style: const TextStyle(fontWeight: FontWeight.w600)),
);
}
}