플러터 테마(theme)

LeeWonjin·2024년 4월 24일
0

플러터

목록 보기
7/15

https://docs.flutter.dev/cookbook/design/themes
https://www.youtube.com/watch?v=oTvQDJOBXmM

일관된 스타일을 앱에 적용하기 위한 기능
매번 똑같은거 또 쓰기 귀찮으니까 미리 적어놓고 갖다쓰자

웹에서 전역스타일에 다 박아놓고 갖다쓰거나,
css in js로 컴포넌트에 스타일을 내재화시키는게 가능한지도 알아봐야 될듯

머티리얼/쿠퍼티노 앱을 쓰자

우리 모두의 정신건강을 위해서 머티리얼을 쓰자.

대충 컨셉은 이렇다

  • MaterialApp의 theme 프로퍼티의 값으로 ThemeData타입의 변수를 던저준다.
  • --> 앱이 실행됐을 때 context에 테마 내용이 들어간다.
  • --> 스타일을 적용할 부분에서 Theme.of(context)로 접근해서 스타일을 가져온다. 마치 전역변수 접근하듯이.

ThemeData 정의

이렇게 만든다

ThemeData _themeData = ThemeData(
  useMaterial3 : true,
  colorScheme : ColorScheme( 대충 색깔 정하는 파라미터 )
  textTheme : TextTheme( 대충 텍스트 케이스별로 스타일 정하는 파라미터 ),
);

ThemeData의 생성자에는 구체적으로(하지만 대충) 아래 내용이 들어갈 수 있다.

  • colorScheme : 색상 팔레트 어떻게 만들거임?
    • e.g., Primary, Secondary (혹은 ternary까지) 색깔이 뭐냐?
    • fromSeed 메소드를 쓰면 색 하나만 던져주고 자동으로 팔레트를 만들 수 있다. (행복하다)
  • textTheme : 텍스트 어떻게 보여줄거임?

정의한 ThemeData 갖다쓰기

이렇게 머티리얼 앱 (콘텍스트)에 박아넣는다

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  
  Widget build(BuildContext context) {
  	return MaterialApp(
      title : 'demo',
      theme : _themeData, // 위 코드블럭에서 정의한 그거
      home : HomePage(),
    );
  }
}

그리고 콘텍스트에서 테마를 꺼내서 이렇게 쓴다

class HomePage extends StatelessWidget {
  const HomePage({super.key});
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar : 대충 앱바 뭐시기,
      body : Column(
        children : [
          Text( // 스타일을 통째로 그냥 꺼내와서 던져줘도 된다
            'Comment Ca Va, Mes amis?',
            style : Theme.of(context).textTheme.bodyMedium,
          ),
          Text( // 색깔만 갖다 붙일수도 있다.
            'Oui, Ca Va. Merci',
            style : TextStyle(
              // onPrimary는 primary색상 위에 올리면 잘보이는 색이다.
              color : Theme.of(context).colorScheme.onPrimary,
              backgroundColor: Theme.of(context).colorScheme.primary
            ),
          ),
        ],
    );
  }
}

예시

구글폰트 패키지 : pub add google_fonts

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

void main() {
  runApp(const MyApp());
}

// 테마 내용 정의
ThemeData _themeData = ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed( 
      // fromSeed는 색 하나 고르면 알아서 색상 파레트 만들어줌.
      seedColor: Colors.green, // 기준 색상.
      brightness: Brightness.light, // light or dark
    ),
    textTheme: TextTheme(
      displayLarge: const TextStyle(
        fontSize: 50,
        fontWeight: FontWeight.bold,
      ),
      titleLarge: const TextStyle(
        fontSize: 30,
        fontStyle: FontStyle.italic,
      ),
      bodyLarge: TextStyle(color: Colors.red),
      // 별 일 없으면 bodyMedium이 텍스트의 기본 스타일로 지정됨
      bodyMedium: GoogleFonts.pacifico(color: Colors.green),
      bodySmall: TextStyle(color: Colors.blue),
      displaySmall: GoogleFonts.pacifico(),
    ));

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

  
  Widget build(BuildContext context) {
    const appTitle = 'Theme Demo';

    return MaterialApp(
      title: appTitle,
      theme: _themeData, // context에 테마 박아넣기
      home: const HomePage(
        title: appTitle,
      ),
    );
  }
}

// context에 들어간 테마 사용하는 예시
class HomePage extends StatelessWidget {
  const HomePage({super.key, required this.title});
  final String title;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        backgroundColor: Theme.of(context).colorScheme.primary,
      ),
      body: GridView.count(
        crossAxisCount: 2,
        children: List.generate(20, (index) {
          return Center(
            child: Text('Item $index',
                style: Theme.of(context).textTheme.bodyMedium!
                // .copyWith(
                //       color: Theme.of(context).colorScheme.onPrimary,
                //       backgroundColor: Theme.of(context).colorScheme.primary,
                // ),
            ),
          );
        }),
      ),
    );
  }
}

TextTheme의 세부 항목

다섯 가지 종류가 있다.

  • display
  • title
  • headline
  • body
  • label

각각은 small, medium, large를 포함한다.
즉, 15개의 정해진 키가 있다.

displaySmall, displayMedium, displayLarge,
..., labelSmall, labelMedium, labelLarge -> 3개(크기) x 5개(종류) = 15개 키

profile
노는게 제일 좋습니다.

0개의 댓글

관련 채용 정보