Nick Dev

[Flutter] 01. Flutter & Widget ( Scaffold, Center, Container, Row, Column ) 본문

Flutter

[Flutter] 01. Flutter & Widget ( Scaffold, Center, Container, Row, Column )

Nick99 2023. 7. 21. 14:07
반응형
  • Flutter 
    • cross platform이다 (android, ios 등 한번에 작업 가능)
    • 대부분 widget으로 구성되어 있다 → UI의 가장 기본적인 단위
    • widget들간의 관계 : Widget Tree로 표현 가능
  • state
    • stateless widget : 화면 갱신할 필요 없는 정적 화면 구성시 사용하는 widget
    • stateful widget : 특정 상황에서 화면 갱신할 필요 있는 화면 구성 시 사용하는 widget

좌측부터 hot reload, hot restart

  • 변경사항 반영 
    • hot reload : 변경 사항을 build 하지 않으면서 바로 앱에 반영해준다. 즉, 앱의 상태가 변하지 않으며 변경 코드를 반영해준다 ( ex. 폰트 변경, color 변경 등...)
    • hot restart : 변경 사항을 반영할 때 앱을 재시작하며 반영한다. 즉, 앱의 상태가 초기화된다.
    • 하지만 두 방식 모두 재 컴파일 후 빌드하는 것이 아니기 때문에 네이티브 코드나 라이브러리, asset 추가 시에는 반영되지 않을 수 있다. 이 때는 아예 앱을 종료 후 재시작을 해야 될 수 있다.
  • Design Guide 
    • Material Design : Google의 철학이 담긴 디자인 가이드
    • Cupertino Design : Apple의 철학이 담긴 디자인 가이드

home: Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(icon: Icon(Icons.home), onPressed: () {
            print('Tab!');
          },),
          Icon(Icons.play_arrow),
        ],
        centerTitle: false,
        title: Text('This is App bar'),
      ),
  • Scaffold 
    • 앱 화면의 기본적인 골격
    • 기본이 되는 도화지
    • appBar : 앱 상단의 bar 
      • IconButton : app bar에 버튼 icon을 만듦
      • onPressed: () {} :  버튼눌렸을 때 할 동작을 { } 안에 선언
      • centerTitle : false  title이 좌측 / true title이 중앙

return Center(
      child: Container(
        width: 300,
        height: 300,
        padding: EdgeInsets.fromLTRB(10, 12, 10, 12), // pading : container 내부에서 상하좌우에서 각 모서리와 간격 조절
        //margin: EdgeInsets.symmetric(vertical: 24, horizontal: 30), // margin : container 자체가 앱 모서리들과 간격 조절
        decoration: BoxDecoration(
          // container에서 boxdecoration의 경우 밖에 또는 doxdeco 둘 중 하나에만 color가 선언되어야 함 -> boxdeco안에서도 color를 선언할 수 있기 때문
          color: Color(0xFF85D07B),   // FF : 투명도 , 이후 2자리씩 RGB값을 나타냄
          border: Border.all(color: Colors.red, width: 5, style: BorderStyle.solid), //외곽선 그리기
          borderRadius: BorderRadius.circular(100), //외곽선 둥글게
          boxShadow: [
            BoxShadow(color: Colors.black.withOpacity(0.3), offset: Offset(6, 6), blurRadius: 10, spreadRadius: 10), // 음영지게 만들고 검정 그림자를 좀 흐리게 만들 때 withOpacity 사용
            BoxShadow(color: Colors.blue.withOpacity(0.3), offset: Offset(-6, -6), blurRadius: 10, spreadRadius: 10), // 음영지게 만들고 검정 그림자를 좀 흐리게 만들 때 withOpacity 사용

          ]
        ),
        child: Center(child: Container(
            color: Colors.yellow,
            child: Text('Hello Container!'))), // wrap with center -> container의 중앙에 위치시킴
      ),
  • Center Widget
    • 앱의 중앙에 widget을 생성
  • Container Widget
    • width, height : 크기를 값으로 설정할 수 있고, width: double.infinity 로 선언하면 해당 방향으로 무제한
    • padding : container 내부에서 각 모서리에 대한 간격 선언
    • margin : container와 외부 앱 화면 모서리와의 간격
    • decoration : 여러 가지 방식으로 container를 꾸밀 수 있음
      • BoxDecoration : container에서 color를 선언하거나 BoxDecoration 안에서 선언하거나 둘 중 하나에서만 선언해야함
      • border : 외곽선 그리기
      • borderRadius : circular로 선언 시 외곽선 둥글게 가능, 원으로 만들 수 있음
      • boxShadow : container를 offset 방향으로 음양지게 만듦, 그림자를 만든다고 생각하면 됨
        • withOpacity : color에 붙이는 메서드로 색을 흐리게 만들 때 사용

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

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.max,
      children: [

        Expanded(
          flex: 1,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.red,
            child: Text('Container1'),
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
            child: Text('Container2'),
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.green,
            child: Text('Container3'),
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.yellow,
            child: Text('Container4'),
          ),
        ),
      ],
    );
  }
}

  • Row Widget
    • 수평으로 배열, 수평으로만 움직일 수 있음
    • mainAxisSize : (Row의 경우 가로축, Column의 경우 세로축)을 따라 얼마나 많은 공간을 차지해야 하는지를 정의
      • MainAxisSize.max = Row는 사용 가능한 모든 수평 공간을 차지
      • MainAxisSize.min = Row는 자식에 필요한 만큼의 공간만 차지
    • mainAxisAlignment : 가로축을 따라 자식의 정렬을 결정
      • start →  좌측에 붙음, center →  중앙으로, end →  우측에 붙음
    • crossAxisAlignment : 교차 축을 따라 정렬을 결정, 행의 경우 교차 축은 '수직'
      • 자식들이 행 내에서 수직 방향 중으로 중앙에 위치한다는 의미
      • 위의 코드에서는 어떤 값을 하던 위치가 바뀌지 않음 
      • 수직으로 움직일 수 없는 상태이기 때문에
      • 해결하기 위해서는 Container Widget으로 감싼 후 Container의 height를 infinity를 주면 crossAxisAlignment 따라서 start →  맨 위, center →  중앙, end →  맨 아래에 위치하게 된다
      • 왜 Container의 height를 infinity 줘야할지는 고민해보면 좋다
  • Column Widget
    • Row widget과 정반대
    • 수직으로 배열되어 있음
    • mainAxisAlignment는 수평축을 따라 정렬 결정
    • crossAxisAlignment는 수직축을 따라 위치 결정
반응형