Flutter မှာ Custom Font ဘယ်လို ထည့်မလဲ?

Project တွေ လုပ်တဲ့အခါ နဂိုပါတဲ့ Default Font ကို သုံးတာထက် User Experience ပိုကောင်းပြီး App အမျိုးအစားနဲ့လိုက်လျောညီထွေဖြစ်မယ့် font တွေကို သုံးကြလေ့ရှိပါတယ်။ Team နဲ့ လုပ်တဲ့အခါ designer ကပေးတဲ့ guideline တွေကို လိုက်နာပြီး Font တွေကို အသုံးပြုကြရတာမျိုးလဲ​ ရှိပါတယ်။​ ဒီတော့ Flutter project တွေမှာလဲ Font အပြောင်းအလဲလုပ်ပြီး သုံးရဖို့ လိုအပ်ချက်တွေ ရှိလာနိုင်ပါတယ်။ ဒီ tutorial ထဲမှာတော့ Flutter project မှာ Font အပြောင်းအလဲ ဘယ်လိုလုပ်မလဲဆိုတာ ပြောပြ ပေးသွားမှာ ဖြစ်ပါတယ်။

ဒီနေရာမှာ အသုံးပြုပုံ ၃မျိုးရှိပါတယ်။ ကိုယ့် project နဲ့ ကိုက်ညီမယ့် ပုံစံကို အသုံးပြုနိုင်ဖို့ အောက်မှာ ပေးထားတဲ့ ပုံကိုကြည့်ပြီး ဆုံးဖြတ်လို့ရပါတယ်။

Use from Google Font

ပထမဆုံးမေးခွန်းကတော့ ကိုယ်အသုံးပြုမယ့် Font က Google ရဲ့ Official font website ဖြစ်တဲ့ https://fonts.google.com/ မှာ​ရှိမရှိဆိုတာပါ။ ဘာဖြစ်လို့လဲဆိုတော့ အဲ့ဒီမှာ ရှိတဲ့ font တွေကို အသုံးပြုချင်ရင် https://pub.dev/packages/google_fonts ကို project မှာထည့်ပြီးတော့ အလွယ်တကူ အသုံးပြုလို့ရပါတယ်။

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Hello World',
              style: GoogleFonts.oswald(
                textStyle: Theme.of(context).textTheme.displayMedium,
              ),
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    );
  }
}

ဒါကို အသုံးပြုတဲ့အခါ font တွေကို app မှာ တခါထဲထည့်ပြီး build လုပ်ပေးလိုက်တာမျိုးမဟုတ်ဘဲ Runtime ရောက်တော့မှ Google Font ကနေ ဒေါင်းပြီး system ထဲမှာ cache လိုက်တာမျိုးဖြစ်တာကြောင့် app size မှာ Font ကြောင့် ကြီးလာတာမျိုးကို ရှောင်ရှားနိုင်ပါလိမ့်မယ်။ ဒါပေမယ့် Runtime ရောက်တော့မှ Font ကို download ဆွဲတာမျိုးဖြစ်တာကြောင့် အကြောင်းအမျိုးမျိုးကြောင့် Font ကို download ဆွဲမရတာမျိုး ကြုံတွေ့နိုင်ပါတယ်။

Use from package

တကယ်လို့ Font က Google Font မှာ မရှိတာမျိုးကြောင့်ပဲဖြစ်ဖြစ်၊ Font ကို download ဆွဲဖို့မလိုအောင်ပဲဖြစ်ဖြစ် တခါထဲ app နဲ့အတူ ထည့်ပေးချင်တဲ့အခါ ကိုယ်ထည့်ပေးမယ့် font က အခု project တခုထဲအတွက်လား ဒါမှမဟုတ် design system လိုမျိုးဖြစ်ပြီးတော့ တခြား app တွေမှာပါ အသုံးပြုဖို့လိုသလား စဥ်းစားဖို့လိုပါမယ်။ တကယ်လို့ app တခုပြီးတခုလဲ လုပ်နေတယ်၊ ခဏခဏလဲသုံးနေရမယ့် အခြေအနေမျိုးဆို package လိုမျိုးလုပ်ပြီးတော့ reusable ဖြစ်အောင် လုပ်ထားတာ ပိုကောင်းပါတယ်။

How to create a package for fonts?

အရင်ဆုံး ကိုယ်အခုလုပ်နေတဲ့ project ထဲမှာ မဟုတ်ဘဲ အပြင်သင့်တော်တဲ့ တနေရာရာမှာ flutter package ကို create လုပ်ပါမယ်။ Project ထဲမှာလုပ်လဲ ရသားနဲ့ ဘာလို့အပြင်မှာ လုပ်ရသလဲဆိုတော့ ကျွန်တော်တို့ အဓိက ဒီ package လုပ်ရခြင်းအကြောင်းအရင်းက အထပ်ထပ် အခါခါ အသုံးပြုချင်တာဖြစ်တဲ့အတွက်ကြောင့် project codebase ကနေ ခွဲထုတ်ထားပြီး သီးသန့်ထားချင်တဲ့အတွက်ကြောင့်ပဲဖြစ်ပါတယ်။ အောက်မှာပေးထားတဲ့ command ကို run ပြီးတော့ package တခုကို အလွယ်တကူတည်ဆောက်လို့ရပါတယ်။

flutter create acme_fonts --template=package

ပြီးရင် project ရဲ့ lib folder ထဲမှာ fonts ဆိုပြီး folder တခု ဆောက်လိုက်ပါမယ်။​ ပုံမှန် asset တွေ ထည့်တဲ့အခါ lib folder ထဲမှာ မဟုတ်ဘဲ အပြင်မှာ ဆောက်လေ့ရှိတာနဲ့ မတူပါဘူး။ ပြီးရင်တော့ ကိုယ်အသုံးပြုချင်တဲ့ font files တွေကို fonts folder ထဲမှာ ထည့်လိုက်ပါ။

အလွယ်တကူ fonts တွေကို reference လုပ်လို့ရအောင်လို့ acme_fonts.dart ကို ထည့်ထားတဲ့ font နာမည်တွေနဲ့ အခုလိုပဲ ပြင်လိုက်ပါမယ်။

library acme_fonts;

class AcmeFonts {
  static String get inter => 'Inter';
  static String get montserrat => 'Montserrat';
}

Fonts တွေကို သုံးချင်တဲ့အခါ 'Inter' ဆိုပြီး string တွေလျှောက်လိုက်နေစရာမလိုတော့ဘဲ AcmeFonts.inter လို့ခေါ်လိုက်တာနဲ့ အသုံးပြုသွားလို့ရပါပြီ။

Package အတွက် ပြင်ဆင်တာတော့ ဒီလောက်နဲ့တင်ပြီးပါပြီ။ ကျွန်တော်တို့ project တွေမှာ အသုံးပြုဖို့ဆို အခု ပြင်ဆင်ထားတဲ့ package ကို pub.dev မှာ တင်ပြီး သုံးတာရယ်, github repository မှာတင်ပြီး သုံးတာရယ်ဆိုပြီး နည်းလမ်း၂ခုရှိပါတယ်။ pub.dev မှာ တင်ရင်တော့ public အနေနဲ့ ဖြစ်သွားပြီး လူတိုင်း အသုံးပြုလို့မှာကိုတော့ သတိပြုဖို့လိုပါမယ်။ ကိုယ့် project တွေမှာပဲ သီးသန့်သုံးစွဲချင်တာမျိုးဖြစ်ဖြစ်၊ ပိုက်ဆံပေးဝယ်ထားရတဲ့ font တွေပါလို့ဖြစ်ဖြစ် github မှာ private repo အနေနဲ့တင်ပြီး အသုံးပြုလို့လဲရပါတယ်။ Repository ကိုတော့ ssh access ရှိနေရမှာဖြစ်ပါတယ်။ Public repo အနေနဲ့ အသုံးပြုမယ်ဆိုလဲ ရပါတယ်။

အခု ကျွန်တော်တို့ font တွေအသုံးပြုမယ့် project ကို သွားပြီးလိုအပ်တဲ့ ပြင်ဆင်မှုတွေ ဆက်လုပ်ပါမယ်။ အရင်ဆုံး pubspec.yaml မှာ ပြင်ဆင်စရာတွေ လုပ်ပါမယ်။

Add the dependency

  • From Github
dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2

  acme_fonts:
    git:
      url: https://github.com/arkarmintun1/acme_fonts.git
      ref: main

dependencies section အောက်ထဲမှာ acme_fonts package နဲ့ github က အသုံးပြုမယ့် url နဲ့ branch ကို ထည့်ပါမယ်။

  • From pub.dev
flutter pub add acme_fonts

တကယ်လို့ pub.dev မှာ တင်ပြီး သုံးမယ်ဆိုရင်တော့ အခု command ကို run ပြီးတော့ သွင်းလို့ရပါတယ်။

Add the fonts

  fonts:
    - family: Inter
      fonts:
        - asset: packages/acme_fonts/fonts/Inter-Thin.ttf
          weight: 100
        - asset: packages/acme_fonts/fonts/Inter-ExtraLight.ttf
          weight: 200
        - asset: packages/acme_fonts/fonts/Inter-Light.ttf
          weight: 300
        - asset: packages/acme_fonts/fonts/Inter-Regular.ttf
          weight: 400
        - asset: packages/acme_fonts/fonts/Inter-Medium.ttf
          weight: 500
        - asset: packages/acme_fonts/fonts/Inter-SemiBold.ttf
          weight: 600
        - asset: packages/acme_fonts/fonts/Inter-Bold.ttf
          weight: 700
        - asset: packages/acme_fonts/fonts/Inter-ExtraBold.ttf
          weight: 800
        - asset: packages/acme_fonts/fonts/Inter-Black.ttf
          weight: 900
    - family: Montserrat
      fonts:
        - asset: packages/acme_fonts/fonts/Montserrat-Thin.ttf
          weight: 100
        - asset: packages/acme_fonts/fonts/Montserrat-ExtraLight.ttf
          weight: 200
        - asset: packages/acme_fonts/fonts/Montserrat-Light.ttf
          weight: 300
        - asset: packages/acme_fonts/fonts/Montserrat-Regular.ttf
          weight: 400
        - asset: packages/acme_fonts/fonts/Montserrat-Medium.ttf
          weight: 500
        - asset: packages/acme_fonts/fonts/Montserrat-SemiBold.ttf
          weight: 600
        - asset: packages/acme_fonts/fonts/Montserrat-Bold.ttf
          weight: 700
        - asset: packages/acme_fonts/fonts/Montserrat-ExtraBold.ttf
          weight: 800
        - asset: packages/acme_fonts/fonts/Montserrat-Black.ttf
          weight: 900

pubspec.yaml  ရဲ့ custom font တွေ ထည့်ဖို့ပေးထားတဲ့နေရာမှာ ကိုယ်အသုံးပြုမယ့် font တွေကို ထည့်ပါမယ်။ Font file တွေကို အပေါ်က ထည့်ထားတဲ့ acme_fonts package ကနေပြီး အသုံးပြုသွားတာပါ။

ဒါပြီးရင်တော့ font ထည့်တာ ပြီးသွားပါပြီး Flutter Widget တွေမှာ အခုလိုစပြီး အသုံးပြုနိုင်ပါပြီ။

Text(
  'You have pushed the button this many times:',
  style: TextStyle(
    fontFamily: AcmeFonts.montserrat,
    fontWeight: FontWeight.bold,
  ),
),

Use from project

တကယ်လို့ package အနေနဲ့မလုပ်ဘဲ လက်ရှိ project ထဲမှာပဲ ထည့်ချင်တာမျိုးဆိုရင်တော့ project root foder ထဲမှာ assets/fonts ဆိုတဲ့ folder ပြုလုပ်ပြီး ကျွန်တော်တို့ အသုံးပြုချင်တဲ့ font တွေကို ထည့်လိုက်ပါမယ်။

ပြီးရင် pubspec.yaml ရဲ့ font section မှာ အခုလိုပဲ ပြင်ဆင်ပါမယ်။

  fonts:
    - family: Inter
      fonts:
        - asset: assets/fonts/Inter-Thin.ttf
          weight: 100
        - asset: assets/fonts/Inter-ExtraLight.ttf
          weight: 200
        - asset: assets/fonts/Inter-Light.ttf
          weight: 300
        - asset: assets/fonts/Inter-Regular.ttf
          weight: 400
        - asset: assets/fonts/Inter-Medium.ttf
          weight: 500
        - asset: assets/fonts/Inter-SemiBold.ttf
          weight: 600
        - asset: assets/fonts/Inter-Bold.ttf
          weight: 700
        - asset: assets/fonts/Inter-ExtraBold.ttf
          weight: 800
        - asset: assets/fonts/Inter-Black.ttf
          weight: 900
    - family: Montserrat
      fonts:
        - asset: assets/fonts/Montserrat-Thin.ttf
          weight: 100
        - asset: assets/fonts/Montserrat-ExtraLight.ttf
          weight: 200
        - asset: assets/fonts/Montserrat-Light.ttf
          weight: 300
        - asset: assets/fonts/Montserrat-Regular.ttf
          weight: 400
        - asset: assets/fonts/Montserrat-Medium.ttf
          weight: 500
        - asset: assets/fonts/Montserrat-SemiBold.ttf
          weight: 600
        - asset: assets/fonts/Montserrat-Bold.ttf
          weight: 700
        - asset: assets/fonts/Montserrat-ExtraBold.ttf
          weight: 800
        - asset: assets/fonts/Montserrat-Black.ttf
          weight: 900

ပြီးရင်တော့ font တွေကို Flutter Widget တွေမှာ စပြီး အသုံးပြလို့ရပါပြီ။

Text(
  'You have pushed the button this many times:',
  style: TextStyle(
    fontFamily: 'Inter',
    fontWeight: FontWeight.bold,
  ),
),