Flutter

[Flutter] Theme 파일 분리와 추가 내용

hminor 2023. 8. 8. 19:01
반응형

import 문법과 ThemeData 추가 내용

  • 이전 숙제 보강 내용
    • elevation 은 그림자 크기를 의미
    • appBar 생성 시 하단 border 같은 부분에 그림자가 있는데 해당 그림자를 조절할 수 있는 속성!
  • import 문법
    • 지난 시간에 배운 ThemeData() 위젯이 현재는 main.dart 파일 내에 위치해서 파일 코드는 여전히 길게 존재하게 되는데
    • 해당 코드를 다른 파일로 빼서 실질적인 코드만 존재하도록 해주기!
  • main.dart 파일이 있는 lib 폴더에 아무 작명의 dart 파일을 생성
    • 강사님은 style.dart 라고 작명하심.
    • 이후 변수에 main.dart 파일에서 작성한 ThemeData() Block 부분을 잘라서 붙여넣기
  • 이후 style.dart 파일에는 flutter 기본 위젯을 사용하기 위한 셋팅이 안되어 있기에
    • main.dart 파일의 상단에 import 되어 있는
      • import 'package:flutter/material.dart'; 를 style.dart 파일의 상단에 추가하기
    import 'package:flutter/material.dart';
    
    var theme = ThemeData(
        appBarTheme: AppBarTheme(
            titleTextStyle: TextStyle(color: Colors.black, fontSize: 22),
            color: Colors.white,
            elevation: 1,
            actionsIconTheme:  IconThemeData(
                size: 30,
                color: Colors.black
            )
        )
    );
    
  • 이제 main.dart 파일에서 styel.dart에서 생성한 변수 theme를 사용하기
  • import './style.dart'; void main() { runApp( MaterialApp( theme: theme, home: MyApp() ) ); }
  • 다만 이렇게 사용하게 되면 변수의 중복이 발생 할 수 있기에 변수의 중복을 방지하는 방법이 있다.
    • alias
      • import 뒤에 as를 사용해 별칭을 작성 후 해당 변수를 사용하기
      import 'package:flutter/material.dart';
      import './style.dart' as style;
      void main() {
        runApp(
          MaterialApp(
            theme: style.theme,
            home: MyApp()
          )
        );
      }
      
  • 그리고 style.dart 파일에서 만든 변수를 다른 파일에서 사용하지 못하도록 하는 방법
    • _
      • 변수 생성 시 _(언더바)를 변수 앞에 붙이게 되면 다른 파일에서 import 하더라도 사용할 수 없게 된다.
  • ThemeData() 안의 버튼 스타일링
    • 버튼 스타일링으로는 primarySwatch 와 같은 다른 방법도 있지만 불편하게 되어 있기에
    • 그냥 textButtonTheme 파라미터를 사용해서 아래와 같이 사용하여 스타일링 하기!
      • style 파라미터의 값으로 TextButton.styleFrom을 사용
      textButtonTheme: TextButtonThemeData(
          style: TextButton.styleFrom(
            backgroundColor: Colors.amber
          )
        ),
      
  • 레이아웃 중간에 해당 자식들의 모든 글자 색상 또는 스타일이 달라졌으면 해서 ThemeData()를 생성하는 것 또한 가능하다
    • 방법으로는 만약 body에 있는 Container() 위젯을 분기로 달라졌으면 한다고 했을 때
    • Container를 선택 후 전구 버튼을 클릭해서 widget을 선택 후
    • 해당 widget을 Theme로 작성 후
      • 파라미터 값으로 data를 주소 ThemeData() 위젯을 추가하기
    • 이렇게 하게 되면 가장 child에 있는 Container 또는 다른 위젯들은
      • 해당 ThemeData를 우선 적용하게 된다.
      body: Theme(
          data: ThemeData(),
          child: Container()
        )
      
  • 그리고 원하는 ThemeData 안의 내용을 불러오기
    • style: Theme.of(context).??? 를 사용하는 방법
      • Theme에서 ??? 를 찾아서 가져오는 코드가 된다.
    • 예시로 Theme이라는 위젯에 있는 textTheme 안에 있는 bodyText2로 지정한 스타일을 가져오려면
      • Theme.of(context).textTheme.bodyText2 를 style의 값으로 넣어주게 되면 된다.
    • 여기서 theme은 상단의 MaterialApp에 있는 파라미터 theme에 있는 위젯을 의미
    • 불편하면 그냥 변수에 담아서 사용하는게 더 편할지도?

숙제

인스타그램처럼 하단에 아이콘을 배운것을 기반하여 추가하기

  • 우선 처음 theme를 사용해서 스타일링을 적용하려 했는데 bottomNavigationBarTheme를 적용해도 main.dart의 bottomNavigationBar에 적용되지 않았다.
  • 그래서 이것 저것 찾아본 결과
    • main.dart에서 bottomNavigationBar의 파라미터 값으로 bottomNavigationBar() 위젯을 사용하며 해당 위젯의 items 속성 안에
    • BottomNavigationBarItem 위젯으로 icon과 label을 추가해줘야 했다.
  • 그리고 label을 지우고 싶어서 그냥 빈 문자열만 넣어줬을때 빈 공백이 생겨 포지션은 여전히 원하는대로 되지 않아 찾아본 결과
  • 해당 속성 역시 따로 적용을 해줬어야 했다.
// main.dart
import 'package:flutter/material.dart';
import './style.dart' as style;
void main() {
  runApp(
    MaterialApp(
      theme: style.theme,
      home: MyApp()
    )
  );
}


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

  var a = TextStyle( color: Colors.pinkAccent);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Instagram'),
          actions: [
            IconButton(
              onPressed: (){},
              icon: Icon(Icons.add_box_outlined)
            )
          ],
        ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home_outlined),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.shopping_bag_outlined),
            label: 'Shopping',
          ),
        ],
        showSelectedLabels: false, // 선택된 아이템의 레이블 숨김
        showUnselectedLabels: false, // 선택되지 않은 아이템의 레이블 숨김
      ),
        // bottomNavigationBar: Container(),
    );
  }
}
// style.dart
import 'package:flutter/material.dart';

var theme = ThemeData(
    appBarTheme: AppBarTheme(
        titleTextStyle: TextStyle(color: Colors.black, fontSize: 22),
        color: Colors.white,
        elevation: 1,
        actionsIconTheme:  IconThemeData(
            size: 30,
            color: Colors.black
        )
    ),
  bottomNavigationBarTheme: BottomNavigationBarThemeData(
    selectedItemColor: Colors.black,
    unselectedItemColor: Colors.black
  )
);