Kartu Profil Keren dengan Flutter

Ingin membuat kartu profil digital yang keren dengan Flutter? Berikut ini adalah contoh **profil interaktif** dari Mochammad Alfin Fauzan, lengkap dengan hobi, cita-cita, dan tombol “Hubungi Saya” yang bisa langsung menampilkan email dan nomor HP.


Kamu bisa menyesuaikan **foto, nama, hobi, dan kontak** sesuai kebutuhan.




Tampilan Profil :


        Link: https://zk2ck06z5k2cl.zapp.page/#/


Nama: Mochammad Alfin Fauzan

Sekolah: SMKN 1 Banjar – XI RPL 1

Hobi: Badminton, Ngoding, mendengarkan musik, mendesain UI/UX, eksplorasi teknologi baru

Cita-cita: Menjadi software engineer profesional dan desainer UI/UX yang berpengaruh

Kontak:


  Email: [mochalfin.fauzan@gmail.com](mailto:mochalfin.fauzan@gmail.com)

  Nomor HP: +62 89503167276


Tampilan profil menggunakan *warna merah maroon dan hitam*, dengan animasi ringan pada foto profil, card hobi dan cita-cita yang gradient, serta tombol interaktif untuk menghubungi langsung. 


 *Kode Flutter Lengkap*

dart

import 'package:flutter/material.dart';

import 'package:flutter/services.dart'; // Untuk copy ke clipboard


void main() => runApp(const MyProfileApp());


class MyProfileApp extends StatelessWidget {

  const MyProfileApp({super.key});


  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      title: 'Kartu Profil Keren',

      debugShowCheckedModeBanner: false,

      theme: ThemeData(

        useMaterial3: true,

        fontFamily: 'Poppins',

        colorScheme: ColorScheme.fromSeed(seedColor: Colors.redAccent),

      ),

      home: const ProfilePage(),

    );

  }

}


class ProfilePage extends StatelessWidget {

  const ProfilePage({super.key});


  void _showContactDialog(BuildContext context) {

    showDialog(

      context: context,

      builder: (context) => AlertDialog(

        backgroundColor: const Color(0xFF330000),

        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),

        title: const Text(

          'Hubungi Saya',

          style: TextStyle(

            color: Colors.white,

            fontWeight: FontWeight.bold,

          ),

        ),

        content: Column(

          mainAxisSize: MainAxisSize.min,

          children: const [

            ContactRow(

              label: 'Email',

              value: 'mochalfin.fauzan@gmail.com',

            ),

            SizedBox(height: 12),

            ContactRow(

              label: 'Nomor HP',

              value: '+62 89503167276',

            ),

          ],

        ),

        actions: [

          TextButton(

            onPressed: () => Navigator.pop(context),

            child: const Text(

              'Tutup',

              style: TextStyle(color: Colors.redAccent),

            ),

          ),

        ],

      ),

    );

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      backgroundColor: Colors.black,

      appBar: AppBar(

        backgroundColor: const Color(0xFF800000),

        centerTitle: true,

        elevation: 6,

        title: const Text(

          'Kartu Profil Keren',

          style: TextStyle(

            color: Colors.white,

            fontWeight: FontWeight.bold,

            letterSpacing: 1.2,

          ),

        ),

      ),

      body: SingleChildScrollView(

        padding: const EdgeInsets.symmetric(vertical: 20),

        child: Center(

          child: Column(

            children: [

              // FOTO PROFIL

              TweenAnimationBuilder(

                tween: Tween<double>(begin: 0.8, end: 1),

                duration: const Duration(milliseconds: 800),

                curve: Curves.elasticOut,

                builder: (context, double scale, child) {

                  return Transform.scale(scale: scale, child: child);

                },

                child: const CircleAvatar(

                  radius: 65,

                  backgroundImage: AssetImage(

                    'assets/alfin.jpg',

                  ),

                ),

              ),

              const SizedBox(height: 18),


              // NAMA & JURUSAN

              const Text(

                'Mochammad Alfin Fauzan',

                style: TextStyle(

                  color: Colors.white,

                  fontSize: 28,

                  fontWeight: FontWeight.bold,

                  shadows: [

                    Shadow(

                      offset: Offset(1, 1),

                      blurRadius: 3,

                      color: Colors.redAccent,

                    ),

                  ],

                ),

              ),

              const SizedBox(height: 6),

              const Text(

                'SMKN 1 Banjar – XI RPL 1',

                style: TextStyle(

                  color: Colors.white70,

                  fontSize: 15,

                  letterSpacing: 0.5,

                ),

              ),

              const SizedBox(height: 20),


              // CARD HOBI

              ProfileCard(

                title: 'Hobi',

                description:

                    'Badminton, Ngoding, mendengarkan musik, mendesain UI/UX, dan eksplorasi teknologi baru.',

                icon: Icons.star,

                gradient: const LinearGradient(

                  colors: [Color(0xFFB71C1C), Color(0xFFB71C1C)],

                  begin: Alignment.topLeft,

                  end: Alignment.bottomRight,

                ),

              ),

              const SizedBox(height: 20),


              // CARD CITA-CITA

              ProfileCard(

                title: 'Cita-Cita',

                description:

                    'Menjadi seorang software engineer profesional dan desainer UI/UX yang berpengaruh.',

                icon: Icons.lightbulb,

                gradient: const LinearGradient(

                  colors: [Color(0xFFB71C1C), Color(0xFF800000)],

                  begin: Alignment.topLeft,

                  end: Alignment.bottomRight,

                ),

              ),

              const SizedBox(height: 30),


              // TOMBOL HUBUNGI SAYA

              ElevatedButton.icon(

                onPressed: () => _showContactDialog(context),

                icon: const Icon(Icons.chat_bubble_outline, color: Colors.white),

                label: const Text(

                  'Hubungi Saya',

                  style: TextStyle(

                    color: Colors.white,

                    fontWeight: FontWeight.bold,

                  ),

                ),

                style: ElevatedButton.styleFrom(

                  backgroundColor: const Color(0xFFB71C1C),

                  padding:

                      const EdgeInsets.symmetric(horizontal: 32, vertical: 16),

                  shape: RoundedRectangleBorder(

                    borderRadius: BorderRadius.circular(16),

                  ),

                  elevation: 8,

                ),

              ),

            ],

          ),

        ),

      ),

    );

  }

}


// Widget Card Keren untuk Hobi / Cita-cita

class ProfileCard extends StatelessWidget {

  final String title;

  final String description;

  final IconData icon;

  final Gradient gradient;


  const ProfileCard({

    super.key,

    required this.title,

    required this.description,

    required this.icon,

    required this.gradient,

  });


  @override

  Widget build(BuildContext context) {

    return Container(

      width: 320,

      padding: const EdgeInsets.all(20),

      decoration: BoxDecoration(

        gradient: gradient,

        borderRadius: BorderRadius.circular(25),

        boxShadow: [

          BoxShadow(

            color: Colors.redAccent.withOpacity(0.5),

            blurRadius: 15,

            offset: const Offset(0, 6),

          ),

        ],

      ),

      child: Row(

        children: [

          Container(

            decoration: BoxDecoration(

              shape: BoxShape.circle,

              color: Colors.white24,

            ),

            padding: const EdgeInsets.all(12),

            child: Icon(icon, color: Colors.white, size: 28),

          ),

          const SizedBox(width: 16),

          Expanded(

            child: Column(

              crossAxisAlignment: CrossAxisAlignment.start,

              children: [

                Text(

                  title,

                  style: const TextStyle(

                    color: Colors.white,

                    fontSize: 18,

                    fontWeight: FontWeight.bold,

                    letterSpacing: 0.5,

                  ),

                ),

                const SizedBox(height: 6),

                Text(

                  description,

                  style: const TextStyle(

                    color: Colors.white70,

                    fontSize: 14,

                    height: 1.4,

                  ),

                ),

              ],

            ),

          ),

        ],

      ),

    );

  }

}


// Widget untuk baris kontak

class ContactRow extends StatelessWidget {

  final String label;

  final String value;


  const ContactRow({super.key, required this.label, required this.value});


  @override

  Widget build(BuildContext context) {

    return Row(

      children: [

        Text(

          '$label: ',

          style: const TextStyle(

            color: Colors.white,

            fontWeight: FontWeight.bold,

          ),

        ),

        Expanded(

          child: Text(

            value,

            style: const TextStyle(color: Colors.white70),

          ),

        ),

        IconButton(

          icon: const Icon(Icons.copy, color: Colors.white70, size: 20),

          onPressed: () {

            Clipboard.setData(ClipboardData(text: value));

            ScaffoldMessenger.of(context).showSnackBar(

              SnackBar(

                content: Text('$label berhasil disalin!'),

                backgroundColor: Colors.redAccent,

                duration: const Duration(seconds: 2),

              ),

            );

          },

        ),

      ],

    );

  }

}

Berikut penjelasan lengkap tentang cara kerja dan fungsi kode Flutter “Kartu Profil Digital Keren” di atas 👇


🧱 1. Struktur Dasar Aplikasi

void main() => runApp(const MyProfileApp());

👉 Baris ini adalah titik awal program Flutter.
Aplikasi dijalankan dengan memanggil widget utama bernama MyProfileApp.


🎨 2. Widget Utama: MyProfileApp

class MyProfileApp extends StatelessWidget { ... }

Widget ini berfungsi sebagai root dari aplikasi.
Di dalamnya terdapat:

  • MaterialApp → untuk mengatur tema, judul, dan halaman utama.
  • ThemeData → mengatur warna utama (redAccent), font (Poppins), dan gaya tampilan umum.
  • home: ProfilePage() → menampilkan halaman profil utama.

👤 3. Halaman Utama: ProfilePage

Widget ini menampilkan isi dari kartu profil digital.
Bagian-bagian pentingnya:

🟥 a. AppBar

AppBar(
  backgroundColor: const Color(0xFF800000),
  centerTitle: true,
  title: const Text('Kartu Profil Keren'),
)
  • Warna merah maroon.
  • Judul di tengah.
  • Sedikit efek bayangan (elevation).

🖼️ b. Foto Profil (Animasi)

TweenAnimationBuilder(
  tween: Tween<double>(begin: 0.8, end: 1),
  duration: const Duration(milliseconds: 800),
  curve: Curves.elasticOut,
  builder: ...
)
  • TweenAnimationBuilder membuat efek animasi “zoom in lembut” pada foto profil.
  • begin: 0.8 → end: 1 artinya gambar membesar dari 80% ke ukuran normal.
  • Efek elasticOut memberi kesan melenting lembut.

🏫 c. Nama & Sekolah

Text('Mochammad Alfin Fauzan', ...)

Menampilkan nama dan sekolah dengan:

  • Warna putih dan bayangan merah (Shadow) agar kontras di background hitam.
  • Font besar dan tebal untuk penegasan identitas.

⭐ d. Kartu “Hobi” dan “Cita-cita”

Menggunakan widget khusus:

ProfileCard(
  title: 'Hobi',
  description: 'Badminton, Ngoding, mendengarkan musik...',
  icon: Icons.star,
  gradient: ...
)

Widget ini menampilkan teks dengan latar gradasi (gradient) merah tua dan efek bayangan (boxShadow).

Fungsi di dalam ProfileCard:

  • Container → membungkus seluruh isi dengan dekorasi dan padding.
  • Row → membagi ikon dan teks secara horizontal.
  • Icon → menampilkan simbol seperti bintang atau lampu ide.
  • Text → menjelaskan isi dari kartu (hobi atau cita-cita).

💬 e. Tombol “Hubungi Saya”

ElevatedButton.icon(
  onPressed: () => _showContactDialog(context),
  label: Text('Hubungi Saya'),
)
  • Ketika ditekan, memanggil fungsi _showContactDialog(context) untuk menampilkan jendela pop-up berisi kontak.

📞 4. Dialog Kontak (_showContactDialog)

showDialog(
  builder: (context) => AlertDialog(
    backgroundColor: const Color(0xFF330000),
    title: Text('Hubungi Saya'),
    content: Column(children: [...]),
  ),
);

Fungsi ini menampilkan pop-up (AlertDialog) dengan dua baris kontak:

  • Email
  • Nomor HP

Masing-masing dibuat menggunakan widget ContactRow.


📋 5. Widget ContactRow

class ContactRow extends StatelessWidget {
  final String label;
  final String value;
  ...
}

Menampilkan satu baris data kontak (misalnya “Email: ...”)
Ada tombol ikon copy untuk menyalin teks ke clipboard:

Clipboard.setData(ClipboardData(text: value));
ScaffoldMessenger.of(context).showSnackBar(
  SnackBar(content: Text('$label berhasil disalin!'))
);

➡️ Jadi, ketika ikon copy ditekan, teks otomatis tersalin dan muncul notifikasi kecil di bawah layar.


🎨 6. Desain & Warna

  • Warna dominan: hitam (background) dan merah maroon (#800000 & #B71C1C).
  • Font: Poppins.
  • Efek visual: bayangan lembut, gradasi, animasi halus.

⚙️ 7. Aset Gambar

backgroundImage: AssetImage('assets/alfin.jpg')

Untuk menampilkan foto profil, pastikan gambar alfin.jpg sudah disimpan di folder assets/ dan terdaftar di file pubspec.yaml.


🚀 Kesimpulan Cara Kerja

  1. Aplikasi memuat widget utama MyProfileApp.
  2. Halaman utama (ProfilePage) menampilkan profil dengan desain interaktif.
  3. Terdapat animasi, kartu informasi, dan tombol interaktif.
  4. Jika tombol ditekan → muncul pop-up berisi kontak.
  5. Pengguna bisa menyalin email atau nomor HP dengan satu klik.

Komentar

Postingan populer dari blog ini

Macam Macam Sistem Operasi Smartphone

UI/UX Alfin XI RPL1

2 ARTIKEL PENGEMBANGAN GIM