Membuat Aplikasi Dengan Fitur Kirim Pesan Via Whatsaap - Dart Flutter
Tutorial Flutter
Membuat aplikasi dengan fitur Kirim Pesan ke WhatsApp
Pada tutorial ini, kita akan belajar membuat aplikasi berbasis Flutter Web yang memungkinkan pengguna mengirim pesan langsung ke WhatsApp.
Tampilan dibuat modern dengan efek glassmorphism sehingga terlihat elegan dan profesional.
🎯 Tujuan Aplikasi
- Input pesan
- Tombol kirim ke WhatsApp
- Validasi pesan
- UI modern (gradient + glass effect)
- Notifikasi interaktif
🧱 Struktur Dasar Program
1. Main Function
void main() {
runApp(const MyApp());
}
Ini adalah entry point aplikasi Flutter.
2. MaterialApp
MaterialApp(
title: 'CMessege',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
),
);
3. Stateful Widget
class AnonymousMessagePage extends StatefulWidget
Digunakan untuk mengatur state seperti input dan loading.
✏️ Mengelola Input
final TextEditingController _messageController = TextEditingController();
Digunakan untuk membaca input dari pengguna.
📱 Kirim ke WhatsApp
final encodedMessage = Uri.encodeComponent(message);
final whatsappUrl = 'https://wa.me/$_targetPhone?text=$encodedMessage';
Format: https://wa.me/NOMOR?text=PESAN
🎨 UI Design
Gradient
LinearGradient(
colors: [Color(0xFF4A00E0), Color(0xFF2B0054)]
)
Glass Effect
color: Colors.white.withOpacity(0.15)
💡 UX Improvement
- Loading indicator
- Snackbar feedback
- Auto clear input
- Tap luar untuk menutup keyboard
🎯 Kesimpulan
Flutter Web memungkinkan kita membuat aplikasi modern tanpa backend, langsung terhubung ke WhatsApp dengan UI yang menarik.
💻 Source Code Lengkap
Salin dan gunakan kode di bawah ini untuk mencoba langsung project Flutter kamu
import 'package:flutter/material.dart';
import 'dart:html' as html;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CMessege',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
useMaterial3: true,
scaffoldBackgroundColor: Colors.transparent,
),
home: const AnonymousMessagePage(),
);
}
}
class AnonymousMessagePage extends StatefulWidget {
const AnonymousMessagePage({super.key});
@override
State createState() => _AnonymousMessagePageState();
}
class _AnonymousMessagePageState extends State {
final TextEditingController _messageController = TextEditingController();
bool _isSending = false;
// Nomor WhatsApp tujuan (sudah di-set ke nomor Anda)
final String _targetPhone = '6281646881706';
@override
void dispose() {
_messageController.dispose();
super.dispose();
}
void _sendToWhatsApp() async {
final message = _messageController.text.trim();
if (message.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Pesan tidak boleh kosong!'),
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.redAccent,
duration: Duration(seconds: 2),
),
);
return;
}
setState(() {
_isSending = true;
});
final encodedMessage = Uri.encodeComponent(message);
final whatsappUrl = 'https://wa.me/$_targetPhone?text=$encodedMessage';
await Future.delayed(const Duration(milliseconds: 300));
try {
html.window.open(whatsappUrl, '_blank');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Mengirim pesan... 📱'),
behavior: SnackBarBehavior.floating,
backgroundColor: Color(0xFF2A7C6F),
duration: Duration(seconds: 2),
),
);
_messageController.clear();
}
} catch (e) {
if (mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
title: const Text('Pop-up diblokir?'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Browser Anda memblokir tab baru.'),
const SizedBox(height: 12),
const Text('Klik tautan berikut untuk membuka WhatsApp:'),
const SizedBox(height: 12),
SelectableText(whatsappUrl,
style: const TextStyle(color: Colors.blue)),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Tutup'),
),
ElevatedButton(
onPressed: () {
html.window.location.href = whatsappUrl;
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF25D366),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
child: const Text('Buka Manual'),
),
],
),
);
}
} finally {
if (mounted) {
setState(() {
_isSending = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: const Text(
'CMassage.fans',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
letterSpacing: -0.3,
color: Colors.white,
),
),
centerTitle: true,
elevation: 0,
backgroundColor: Colors.transparent,
toolbarHeight: 90,
flexibleSpace: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(width: 8),
],
),
),
),
),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF4A00E0), // Ungu tua
Color(0xFF2B0054), // Ungu kehitaman
Color(0xFF1A0033), // Hitam keunguan
],
),
),
child: SafeArea(
child: Center(
child: SingleChildScrollView(
padding:
const EdgeInsets.symmetric(horizontal: 24, vertical: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Liquid Glass Card
Container(
padding: const EdgeInsets.all(28),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(48),
border: Border.all(
color: Colors.white.withValues(alpha: 0.25),
width: 1.5,
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.2),
blurRadius: 30,
offset: const Offset(0, 10),
spreadRadius: -5,
),
],
),
child: Column(
children: [
const SizedBox(height: 20),
const Text(
'Kirim Pesan',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 8),
Text(
'Kirim pesan langsung ke idola kalian',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.white.withValues(alpha: 0.85),
),
),
const SizedBox(height: 32),
// Input Pesan
Container(
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(32),
border: Border.all(
color: Colors.white.withValues(alpha: 0.3),
width: 1,
),
),
child: TextField(
controller: _messageController,
maxLines: 5,
minLines: 3,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
decoration: InputDecoration(
hintText: 'Ketik pesan di sini...',
hintStyle: TextStyle(
color: Colors.white.withValues(alpha: 0.6),
fontSize: 15,
),
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(
horizontal: 22, vertical: 20),
),
cursorColor: Colors.white,
),
),
const SizedBox(height: 32),
// Tombol Kirim
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _isSending ? null : _sendToWhatsApp,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF4A00E0),
elevation: 0,
padding:
const EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
textStyle: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
child: _isSending
? const SizedBox(
height: 24,
width: 24,
child: CircularProgressIndicator(
strokeWidth: 2.5,
valueColor:
AlwaysStoppedAnimation(
Color(0xFF4A00E0),
),
),
)
: const Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Icon(Icons.send, size: 22),
SizedBox(width: 8),
Text('Kirim via WhatsApp'),
],
),
),
),
const SizedBox(height: 20),
// Catatan anonim
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.security,
size: 14, color: Colors.white70),
const SizedBox(width: 6),
Text(
'Pesan dikirim langsung ke idol, caca ardiansyah',
style: TextStyle(
fontSize: 11,
color: Colors.white.withValues(alpha: 0.7),
),
),
],
),
],
),
),
const SizedBox(height: 24),
],
),
),
),
),
),
),
);
}
}
Komentar
Posting Komentar