[Flutter] 미리 정해놓으면 좋은 것들 (Theme, Icon, Block, Sound...)

2023. 3. 12. 18:58Developers 공간 [Shorts]/Frontend

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 

 


1. What? (현상)

앱을 쭉 만들어가다 보면, 반복되는 테마나 아이콘 등 반복되는 것들에 대해 재정의하는 것보다 미리 const로 정해두는 것이 유리하겠다는 생각이 들기도 합니다.

 

기본적으로 테마의 경우는 아래와 같이 main.dart에서 MaterialApp > theme 로 테마를 정해주도록합니다.

MaterialApp(
  title: 'Flutter Demo',
  //************************************Theme
  theme: Theme.of(context).copyWith(
    primaryColor: kcBackgroundColor,
    focusColor: kcPrimaryColor,
    appBarTheme: AppBarTheme(
      color: kMainIvory,
      iconTheme: IconThemeData(
        color: kMainPink,
      ),
      elevation: 0.0,
    ),
    dialogTheme: DialogTheme(
      titleTextStyle: TextStyle(
          fontSize: 18.0,
          fontFamily: 'Spoqa Han Sans',
          color: Color(0xff333333)),
      contentTextStyle: TextStyle(
          fontSize: 16.0,
          fontFamily: 'Spoqa Han Sans',
          color: Color(0xff333333)),
    ),
    scaffoldBackgroundColor: kMainIvory,
    textTheme: Theme.of(context).textTheme.apply(
    	bodyColor : Colors.black,
    ),
  ),
  //************************************ThemeEnd
  initialRoute: Routes.startupView,
  onGenerateRoute: StackedRouter().onGenerateRoute,
  navigatorKey: StackedService.navigatorKey,
  navigatorObservers: [
    StackedService.routeObserver,
  ],
);
  • Theme.of(context).copyWith() : 기존 속성값을 상속 받아 변경하려는 속성 값을 각각 변경 가능하도록 도와줍니다. 
  • primarColor : kcBackgroundColor : 가장 메인 칼라입니다.(아래 그림 참조)
  • focusColor : Color(0xff828282)) : Text의 input focus(강조)가 필요할 때 넣는 파라미터 입니다.
  • appBarTheme AppBarTheme() : elevation, brightness, iconTheme, textTheme 등 AppBar에 대한 것을 셋팅
  • dialogTheme : DialogTheme() : Dialog 알람 등의 테마를 셋팅
  • scaffoldBackgroundColor : kMainIvory : Scaffold 등 Material의 default color로 보통 배경에 활용
  • textTheme : text의 테마를 정해줍니다.
    • Theme.of(context).textTheme.apply() : copyWith()과 다르게 속성 값을 지정하는 것이 아닌, 추상적인 값을 통해 속성 값을 자동으로 만들어주도록 몇가지의 값을 셋팅해 제공합니다.
    • fontFamily : 'Spoga Han Sans' : 텍스트 테마를 정해줍니다. 
    • bodyColor: Colors.black : 텍스트 색깔을 정해줍니다.
더보기

-----------------------------------------------------------------------------------------------------

  • 위 상속 받지 않고 셋팅하는 방법
theme: ThemeData(
    // Define the default brightness and colors.
    brightness: Brightness.dark,
    primaryColor: Colors.lightBlue[800],

    // Define the default font family.
    fontFamily: 'Georgia',

    // Define the default `TextTheme`. Use this to specify the default
    // text styling for headlines, titles, bodies of text, and more.
    textTheme: const TextTheme(
      displayLarge: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
      titleLarge: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
      bodyMedium: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
    ),
  ),
  •  상속 받지 않고 셋팅시 글자 아래 노란 두줄 등이 생기는 경우, decoration:TextDecoration.none을 넣어줍니다.
Text(
  'Hello',
  style: TextStyle(
	decoration: TextDecoration.none
	), // Set this
)
  • 상속 받지 않고 개별로 셋팅할 때 유용한 GoogleFonts
import 'package:google_fonts/google_fonts.dart';

GoogleFonts.laila(
    fontSize: 30,
    fontWeight: FontWeight.w500,
    color: snapshot.data == index? Colors.black: Colors.grey),                  
),

-----------------------------------------------------------------------------------------------------

[primaryColor, bodyText, accentColor 등 Theme]

  • 위 방법으로 셋팅한 이후에 아래와 같은 방법으로, child Widget에서 불러 사용합니다.
Theme.of(context).textTheme.titleLarge,
Theme.of(context).appBarTheme.titleTextStyle,
Theme.of(context).colorScheme.primary,
Theme.of(context).primaryColor;

 

테마 이외에 기본적으로 셋팅해 놓으면 좋았던 것들을 아래와 같이 정리하고자 합니다.


2. Why? (원인)

  • X

3. How? (해결책)

const double bottomHeight = 65;
double screenWidth(BuildContext context) => MediaQuery.of(context).size.width;
double screenHeight(BuildContext context) => MediaQuery.of(context).size.height;
  • Padding/Margin
const EdgeInsets horizontalPadding = EdgeInsets.symmetric(horizontal: 10);
더보기

-----------------------------------------------------------------------------------------------------

<Padding과 Margin 이란?> 

Padding : 해당 컨테이너의 내부 child까지의 거리 (크기가 변하지 않습니다.)

Margin : 해당 컨테이너 바깥의 공간의 거리 (크기가 변합니다)
** 주의 Center()를 활용하면 Margin 값까지 포함한 전체 크기의 중앙값이 중앙으로 계산된다.

[출처 : https://learncom1234.tistory.com/25]

-----------------------------------------------------------------------------------------------------

  • 모서리
const BorderRadius firstRadius = BorderRadius.only(
  topLeft: Radius.circular(10),
  topRight: Radius.circular(10),
);

const BorderRadius thirdRadius = BorderRadius.all(
	Radius.circular(10)
);

const Border allBorder = Border.all(
    colors.Colors.deepPurpleAccent,
    width:2
)
  • 공간 차지
const Widget horizontalBlock = SizedBox(width: 10.0);
const Widget verticalBlock = SizedBox(height: 2.0);
  • 아이콘
final Icon kArrowBack = Icon(
    Icons.arrow_back_rounded,
    color: Colors.black.withOpacity(0.5),
    size: 24,
);

final ImageIcon button = ImageIcon(
    AssetImage("images/icon.png"),
    color: Colors.red,
    size: 24,
),
더보기

-----------------------------------------------------------------------------------------------------

 <이미지와 사운드 넣는 방법>

Image.asset(
  "images/temp.png",
),

Xfile imageFile;
Image.file(
	File(imageFile.path);
)

Uint8List bytes;
Image.memory(
	bytes,
    fit:BoxFit.cover
)

import 'package:cached_network_image/cached_network_image.dart';
CachedNetworkImage(
    imageUrl: "http://via.placeholder.com/350x150",
    placeholder: (context, url) => CircularProgressIndicator(),
    errorWidget: (context, url, error) => Icon(Icons.error),
    fadeInDuration: Duration(milliseconds: 50),
    fit : Boxfit.cover,
),

import 'package:audioplayers/audio_cache.dart';
 final player = AudioCache();
 player.play('note1.wav');

import 'package:flutter/services.dart';
SystemSound.play(SystemSoundType.click);

-----------------------------------------------------------------------------------------------------

  • Enum 등 선언
enum MyCategory{
    CategoryA,
    CategoryB,
    CategoryC
}
  • 다양한 기본 함수들
import 'package:intl/intl.dart';

class Formatter {
  String getStringFromDatetime(DateTime dateTime) {
    final df = new DateFormat('yyyy/MM/dd');

    return df.format(dateTime);
  }

  String getStringFromDateTimeInString(String str) {
    return str.substring(0, 10);
  }

  String getPriceFromInt(int price) {
    return NumberFormat('###,###,###,###원').format(price);
  }
}

https://docs.flutter.dev/cookbook/design/themes

https://api.flutter.dev/flutter/material/ThemeData-class.html

https://api.flutter.dev/flutter/material/TextTheme-class.html


 

 

 

728x90
반응형