Panduan praktis dan terstruktur mengenai panduan al-quran dengan flutter: konfigurasi tema (part 3) berstandar enterprise. Pelajari konsep, implementasi kode modern, dan tips arsitektur enterprise siap produksi.
Selamat datang di seri tutorial engineering SiHubung! Pada artikel ini, kita akan membedah secara komprehensif implementasi Panduan Al-Quran Dengan Flutter: Konfigurasi Tema (Part 3) Berstandar Enterprise dengan standar kode bersih (clean code), performa tinggi, dan arsitektur siap produksi.

Membangun aplikasi web di era modern memerlukan pondasi yang kokoh. Framework modern memberikan fleksibilitas luar biasa bagi developer untuk menghadirkan fitur kompleks secara cepat tanpa mengabaikan aspek keamanan dan keandalan sistem.

Tahapan Implementasi & Walkthrough Kode

Berikut adalah langkah demi langkah teknis yang dapat Anda ikuti langsung pada codebase Anda:

Tahap 1: Penulisan Kode & Konfigurasi

flutter:
  assets:
    - assets/icons/
  uses-material-design: true

Tahap 2: Penulisan Kode & Konfigurasi

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

TextTheme createTextTheme(
  BuildContext context,
  String bodyFontString,
  String displayFontString,
) {
  TextTheme baseTextTheme = Theme.of(context).textTheme;
  TextTheme bodyTextTheme = GoogleFonts.getTextTheme(
    bodyFontString,
    baseTextTheme,
  );
  TextTheme displayTextTheme = GoogleFonts.getTextTheme(
    displayFontString,
    baseTextTheme,
  );
  TextTheme textTheme = displayTextTheme.copyWith(
    bodyLarge: bodyTextTheme.bodyLarge,
    bodyMedium: bodyTextTheme.bodyMedium,
    bodySmall: bodyTextTheme.bodySmall,
    labelLarge: bodyTextTheme.labelLarge,
    labelMedium: bodyTextTheme.labelMedium,
    labelSmall: bodyTextTheme.labelSmall,
  );
  return textTheme;
}

Tahap 3: Penulisan Kode & Konfigurasi

import "package:flutter/material.dart";

class MaterialTheme {
  final TextTheme textTheme;

  const MaterialTheme(this.textTheme);

  static ColorScheme lightScheme() {
    return const ColorScheme(
      brightness: Brightness.light,
      primary: Color(0xff1f642e),
      surfaceTint: Color(0xff286b34),
      onPrimary: Color(0xffffffff),
      primaryContainer: Color(0xff3a7d44),
      onPrimaryContainer: Color(0xffd5ffd3),
      secondary: Color(0xff4b654b),
      onSecondary: Color(0xffffffff),
      secondaryContainer: Color(0xffccebc9),
      onSecondaryContainer: Color(0xff506b50),
      tertiary: Color(0xff005d83),
      onTertiary: Color(0xffffffff),
      tertiaryContainer: Color(0xff0877a5),
      onTertiaryContainer: Color(0xffebf5ff),
      error: Color(0xffba1a1a),
      onError: Color(0xffffffff),
      errorContainer: Color(0xffffdad6),
      onErrorContainer: Color(0xff93000a),
      surface: Color(0xfff7faf2),
      onSurface: Color(0xff191d18),
      onSurfaceVariant: Color(0xff40493f),
      outline: Color(0xff707a6e),
      outlineVariant: Color(0xffc0c9bc),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xff2d312c),
      inversePrimary: Color(0xff90d794),
      primaryFixed: Color(0xffabf4ae),
      onPrimaryFixed: Color(0xff002107),
      primaryFixedDim: Color(0xff90d794),
      onPrimaryFixedVariant: Color(0xff07521f),
      secondaryFixed: Color(0xffccebc9),
      onSecondaryFixed: Color(0xff08200c),
      secondaryFixedDim: Color(0xffb1ceae),
      onSecondaryFixedVariant: Color(0xff334d34),
      tertiaryFixed: Color(0xffc6e7ff),
      onTertiaryFixed: Color(0xff001e2d),
      tertiaryFixedDim: Color(0xff83cfff),
      onTertiaryFixedVariant: Color(0xff004c6b),
      surfaceDim: Color(0xffd8dbd3),
      surfaceBright: Color(0xfff7faf2),
      surfaceContainerLowest: Color(0xffffffff),
      surfaceContainerLow: Color(0xfff2f5ed),
      surfaceContainer: Color(0xffecefe7),
      surfaceContainerHigh: Color(0xffe6e9e1),
      surfaceContainerHighest: Color(0xffe0e4dc),
    );
  }

  ThemeData light() {
    return theme(lightScheme());
  }

  static ColorScheme lightMediumContrastScheme() {
    return const ColorScheme(
      brightness: Brightness.light,
      primary: Color(0xff004015),
      surfaceTint: Color(0xff286b34),
      onPrimary: Color(0xffffffff),
      primaryContainer: Color(0xff387b42),
      onPrimaryContainer: Color(0xffffffff),
      secondary: Color(0xff233c25),
      onSecondary: Color(0xffffffff),
      secondaryContainer: Color(0xff597459),
      onSecondaryContainer: Color(0xffffffff),
      tertiary: Color(0xff003a54),
      onTertiary: Color(0xffffffff),
      tertiaryContainer: Color(0xff0075a2),
      onTertiaryContainer: Color(0xffffffff),
      error: Color(0xff740006),
      onError: Color(0xffffffff),
      errorContainer: Color(0xffcf2c27),
      onErrorContainer: Color(0xffffffff),
      surface: Color(0xfff7faf2),
      onSurface: Color(0xff0e120e),
      onSurfaceVariant: Color(0xff30382f),
      outline: Color(0xff4c554a),
      outlineVariant: Color(0xff667064),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xff2d312c),
      inversePrimary: Color(0xff90d794),
      primaryFixed: Color(0xff387b42),
      onPrimaryFixed: Color(0xffffffff),
      primaryFixedDim: Color(0xff1c612c),
      onPrimaryFixedVariant: Color(0xffffffff),
      secondaryFixed: Color(0xff597459),
      onSecondaryFixed: Color(0xffffffff),
      secondaryFixedDim: Color(0xff415b42),
      onSecondaryFixedVariant: Color(0xffffffff),
      tertiaryFixed: Color(0xff0075a2),
      onTertiaryFixed: Color(0xffffffff),
      tertiaryFixedDim: Color(0xff005b80),
      onTertiaryFixedVariant: Color(0xffffffff),
      surfaceDim: Color(0xffc4c8c0),
      surfaceBright: Color(0xfff7faf2),
      surfaceContainerLowest: Color(0xffffffff),
      surfaceContainerLow: Color(0xfff2f5ed),
      surfaceContainer: Color(0xffe6e9e1),
      surfaceContainerHigh: Color(0xffdbded6),
      surfaceContainerHighest: Color(0xffcfd3cb),
    );
  }

  ThemeData lightMediumContrast() {
    return theme(lightMediumContrastScheme());
  }

  static ColorScheme lightHighContrastScheme() {
    return const ColorScheme(
      brightness: Brightness.light,
      primary: Color(0xff003410),
      surfaceTint: Color(0xff286b34),
      onPrimary: Color(0xffffffff),
      primaryContainer: Color(0xff0b5521),
      onPrimaryContainer: Color(0xffffffff),
      secondary: Color(0xff19311b),
      onSecondary: Color(0xffffffff),
      secondaryContainer: Color(0xff364f37),
      onSecondaryContainer: Color(0xffffffff),
      tertiary: Color(0xff003045),
      onTertiary: Color(0xffffffff),
      tertiaryContainer: Color(0xff004f6f),
      onTertiaryContainer: Color(0xffffffff),
      error: Color(0xff600004),
      onError: Color(0xffffffff),
      errorContainer: Color(0xff98000a),
      onErrorContainer: Color(0xffffffff),
      surface: Color(0xfff7faf2),
      onSurface: Color(0xff000000),
      onSurfaceVariant: Color(0xff000000),
      outline: Color(0xff262e25),
      outlineVariant: Color(0xff434b41),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xff2d312c),
      inversePrimary: Color(0xff90d794),
      primaryFixed: Color(0xff0b5521),
      onPrimaryFixed: Color(0xffffffff),
      primaryFixedDim: Color(0xff003c13),
      onPrimaryFixedVariant: Color(0xffffffff),
      secondaryFixed: Color(0xff364f37),
      onSecondaryFixed: Color(0xffffffff),
      secondaryFixedDim: Color(0xff203821),
      onSecondaryFixedVariant: Color(0xffffffff),
      tertiaryFixed: Color(0xff004f6f),
      onTertiaryFixed: Color(0xffffffff),
      tertiaryFixedDim: Color(0xff00374f),
      onTertiaryFixedVariant: Color(0xffffffff),
      surfaceDim: Color(0xffb6bab3),
      surfaceBright: Color(0xfff7faf2),
      surfaceContainerLowest: Color(0xffffffff),
      surfaceContainerLow: Color(0xffeff2ea),
      surfaceContainer: Color(0xffe0e4dc),
      surfaceContainerHigh: Color(0xffd2d6ce),
      surfaceContainerHighest: Color(0xffc4c8c0),
    );
  }

  ThemeData lightHighContrast() {
    return theme(lightHighContrastScheme());
  }

  static ColorScheme darkScheme() {
    return const ColorScheme(
      brightness: Brightness.dark,
      primary: Color(0xff90d794),
      surfaceTint: Color(0xff90d794),
      onPrimary: Color(0xff003912),
      primaryContainer: Color(0xff3a7d44),
      onPrimaryContainer: Color(0xffd5ffd3),
      secondary: Color(0xffb1ceae),
      onSecondary: Color(0xff1d361f),
      secondaryContainer: Color(0xff334d34),
      onSecondaryContainer: Color(0xffa0bd9e),
      tertiary: Color(0xff83cfff),
      onTertiary: Color(0xff00344b),
      tertiaryContainer: Color(0xff0877a5),
      onTertiaryContainer: Color(0xffebf5ff),
      error: Color(0xffffb4ab),
      onError: Color(0xff690005),
      errorContainer: Color(0xff93000a),
      onErrorContainer: Color(0xffffdad6),
      surface: Color(0xff101410),
      onSurface: Color(0xffe0e4dc),
      onSurfaceVariant: Color(0xffc0c9bc),
      outline: Color(0xff8a9387),
      outlineVariant: Color(0xff40493f),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xffe0e4dc),
      inversePrimary: Color(0xff286b34),
      primaryFixed: Color(0xffabf4ae),
      onPrimaryFixed: Color(0xff002107),
      primaryFixedDim: Color(0xff90d794),
      onPrimaryFixedVariant: Color(0xff07521f),
      secondaryFixed: Color(0xffccebc9),
      onSecondaryFixed: Color(0xff08200c),
      secondaryFixedDim: Color(0xffb1ceae),
      onSecondaryFixedVariant: Color(0xff334d34),
      tertiaryFixed: Color(0xffc6e7ff),
      onTertiaryFixed: Color(0xff001e2d),
      tertiaryFixedDim: Color(0xff83cfff),
      onTertiaryFixedVariant: Color(0xff004c6b),
      surfaceDim: Color(0xff101410),
      surfaceBright: Color(0xff363a35),
      surfaceContainerLowest: Color(0xff0b0f0b),
      surfaceContainerLow: Color(0xff191d18),
      surfaceContainer: Color(0xff1d211c),
      surfaceContainerHigh: Color(0xff272b26),
      surfaceContainerHighest: Color(0xff323631),
    );
  }

  ThemeData dark() {
    return theme(darkScheme());
  }

  static ColorScheme darkMediumContrastScheme() {
    return const ColorScheme(
      brightness: Brightness.dark,
      primary: Color(0xffa6eda9),
      surfaceTint: Color(0xff90d794),
      onPrimary: Color(0xff002d0c),
      primaryContainer: Color(0xff5ca062),
      onPrimaryContainer: Color(0xff000000),
      secondary: Color(0xffc6e4c3),
      onSecondary: Color(0xff122b15),
      secondaryContainer: Color(0xff7c987b),
      onSecondaryContainer: Color(0xff000000),
      tertiary: Color(0xffb9e2ff),
      onTertiary: Color(0xff00293c),
      tertiaryContainer: Color(0xff4299c9),
      onTertiaryContainer: Color(0xff000000),
      error: Color(0xffffd2cc),
      onError: Color(0xff540003),
      errorContainer: Color(0xffff5449),
      onErrorContainer: Color(0xff000000),
      surface: Color(0xff101410),
      onSurface: Color(0xffffffff),
      onSurfaceVariant: Color(0xffd6dfd1),
      outline: Color(0xffabb5a8),
      outlineVariant: Color(0xff8a9387),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xffe0e4dc),
      inversePrimary: Color(0xff095420),
      primaryFixed: Color(0xffabf4ae),
      onPrimaryFixed: Color(0xff001604),
      primaryFixedDim: Color(0xff90d794),
      onPrimaryFixedVariant: Color(0xff004015),
      secondaryFixed: Color(0xffccebc9),
      onSecondaryFixed: Color(0xff001504),
      secondaryFixedDim: Color(0xffb1ceae),
      onSecondaryFixedVariant: Color(0xff233c25),
      tertiaryFixed: Color(0xffc6e7ff),
      onTertiaryFixed: Color(0xff00131f),
      tertiaryFixedDim: Color(0xff83cfff),
      onTertiaryFixedVariant: Color(0xff003a54),
      surfaceDim: Color(0xff101410),
      surfaceBright: Color(0xff414640),
      surfaceContainerLowest: Color(0xff050805),
      surfaceContainerLow: Color(0xff1b1f1a),
      surfaceContainer: Color(0xff252924),
      surfaceContainerHigh: Color(0xff30342e),
      surfaceContainerHighest: Color(0xff3b3f39),
    );
  }

  ThemeData darkMediumContrast() {
    return theme(darkMediumContrastScheme());
  }

  static ColorScheme darkHighContrastScheme() {
    return const ColorScheme(
      brightness: Brightness.dark,
      primary: Color(0xffc3ffc3),
      surfaceTint: Color(0xff90d794),
      onPrimary: Color(0xff000000),
      primaryContainer: Color(0xff8dd391),
      onPrimaryContainer: Color(0xff000f02),
      secondary: Color(0xffdaf8d6),
      onSecondary: Color(0xff000000),
      secondaryContainer: Color(0xffadcaab),
      onSecondaryContainer: Color(0xff000f02),
      tertiary: Color(0xffe3f2ff),
      onTertiary: Color(0xff000000),
      tertiaryContainer: Color(0xff7accfe),
      onTertiaryContainer: Color(0xff000d16),
      error: Color(0xffffece9),
      onError: Color(0xff000000),
      errorContainer: Color(0xffffaea4),
      onErrorContainer: Color(0xff220001),
      surface: Color(0xff101410),
      onSurface: Color(0xffffffff),
      onSurfaceVariant: Color(0xffffffff),
      outline: Color(0xffe9f3e5),
      outlineVariant: Color(0xffbcc5b8),
      shadow: Color(0xff000000),
      scrim: Color(0xff000000),
      inverseSurface: Color(0xffe0e4dc),
      inversePrimary: Color(0xff095420),
      primaryFixed: Color(0xffabf4ae),
      onPrimaryFixed: Color(0xff000000),
      primaryFixedDim: Color(0xff90d794),
      onPrimaryFixedVariant: Color(0xff001604),
      secondaryFixed: Color(0xffccebc9),
      onSecondaryFixed: Color(0xff000000),
      secondaryFixedDim: Color(0xffb1ceae),
      onSecondaryFixedVariant: Color(0xff001504),
      tertiaryFixed: Color(0xffc6e7ff),
      onTertiaryFixed: Color(0xff000000),
      tertiaryFixedDim: Color(0xff83cfff),
      onTertiaryFixedVariant: Color(0xff00131f),
      surfaceDim: Color(0xff101410),
      surfaceBright: Color(0xff4d514b),
      surfaceContainerLowest: Color(0xff000000),
      surfaceContainerLow: Color(0xff1d211c),
      surfaceContainer: Color(0xff2d312c),
      surfaceContainerHigh: Color(0xff383d37),
      surfaceContainerHighest: Color(0xff444842),
    );
  }

  ThemeData darkHighContrast() {
    return theme(darkHighContrastScheme());
  }

  ThemeData theme(ColorScheme colorScheme) => ThemeData(
    useMaterial3: true,
    brightness: colorScheme.brightness,
    colorScheme: colorScheme,
    textTheme: textTheme.apply(
      bodyColor: colorScheme.onSurface,
      displayColor: colorScheme.onSurface,
    ),
    scaffoldBackgroundColor: colorScheme.surface,
    canvasColor: colorScheme.surface,
  );

  List<ExtendedColor> get extendedColors => [];
}

class ExtendedColor {
  final Color seed, value;
  final ColorFamily light;
  final ColorFamily lightHighContrast;
  final ColorFamily lightMediumContrast;
  final ColorFamily dark;
  final ColorFamily darkHighContrast;
  final ColorFamily darkMediumContrast;

  const ExtendedColor({
    required this.seed,
    required this.value,
    required this.light,
    required this.lightHighContrast,
    required this.lightMediumContrast,
    required this.dark,
    required this.darkHighContrast,
    required this.darkMediumContrast,
  });
}

class ColorFamily {
  const ColorFamily({
    required this.color,
    required this.onColor,
    required this.colorContainer,
    required this.onColorContainer,
  });

  final Color color;
  final Color onColor;
  final Color colorContainer;
  final Color onColorContainer;
}

Tahap 4: Penulisan Kode & Konfigurasi

import 'package:alquran_flutter/home_page.dart';
import 'package:alquran_flutter/theme.dart';
import 'package:alquran_flutter/util.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    TextTheme textTheme = createTextTheme(context, "Quicksand", "Quicksand");

    MaterialTheme theme = MaterialTheme(textTheme);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: theme.light(),
      home: HomePage(),
    );
  }
}

Tahap 5: Penulisan Kode & Konfigurasi

import 'package:alquran_flutter/theme.dart';
import 'package:alquran_flutter/util.dart';

Tahap 6: Penulisan Kode & Konfigurasi

TextTheme textTheme = createTextTheme(context, "Quicksand", "Quicksand");
MaterialTheme theme = MaterialTheme(textTheme);

Tahap 7: Penulisan Kode & Konfigurasi

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}
💡 Tips Rekayasa Perangkat Lunak (SiHubung Engineering Best Practice)

Selalu gunakan pendekatan deklaratif, validasi input seawal mungkin di boundary layer, dan lakukan logging terstruktur untuk memudahkan observability ketika sistem dijalankan di lingkungan cloud produksi.

Kesimpulan

Dengan mengikuti langkah-langkah terstruktur di atas, implementasi modul Anda akan jauh lebih rapi, aman dari bug umum, serta siap diskalakan ke lingkungan produksi.

Nantikan artikel tutorial praktis lainnya seputar fullstack development, microservices, dan otomasi AI di Blog Engineering SiHubung. Selamat mencoba!