상세 컨텐츠

본문 제목

Widgets in Flutter

Coding 배우기

by haghiasophia 2023. 1. 20. 13:38

본문

Basic widgets 가장 근본적인 위젯
Text, Image, Container

// 텍스트를 보여줄 때 Text 위젯을 사용
Text
  '텍스트 위젯',
  style: TextStyle(
    fontSize: 35, // 폰트 크기
    fontWeight: FontWeight.bold, // 폰트 두께
    color: Colors.amber, // 폰트 색상
    color: Colors.amber.withOpacity(0.7), // 폰트 색상 + 투명도
  ),
),

// Container는 Box 형태의 기본적인 위젯으로 다방면으로 많이 사용됨
Container(
  width: 200, // 폭 or width: double.infinity
  height: 200, // 높이 or height: double.infinity
  margin: EdgeInsets.only(top: 24),
  padding: EdgeInsets.all(16),
  color: Colors.amber, // 박스 색상
  child: Text("I Love Flutter!"), // 자식 위젯
),

//Image.network("URL")을 이용하면 URL로 된 이미지를 보여줄 수 있음
Image.network(
  "https://i.ibb.co/CwzHq4z/trans-logo-512.png",
  width: 81,
),
// Image.asset("파일경로")을 이용하는 방법도 있음
Image.asset('image/work1.jpg')
Layout widgets 다른 위젯들을 배열하기 위한 위젯
Colunm, Row, Expanded, SingleChildScrollView

// Column 위젯은 세로 방향으로 여러 위젯을 나열할 때 사용
Column
  mainAxisAlignment: MainAxisAlignment.center,
  children: [ // 자식 위젯들
    Text("위젯1"),
    Text("위젯2"),
  ],
),

// Row 위젯은 가로 방향으로 여러 위젯을 나열할 때 사용
Row
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [ // 자식 위젯들
    Icon(Icons.home),
    Icon(Icons.account-circle),
   Icon(Icons.settings),
    Icon(Icons.check-circle),
  ],
),

// Expand 위젯은 Column, Row, Flex의 자식으로 사용하며, 부모의 남은 부분은 전부 채우게 사용
Row(
  children: [
    Expanded(
      child: TextField(
        controller: jobController,
        decoration: InputDecoration(
          hintText: "하고 싶은 일을 입력해주세요.",
        ),
      ),
    ),
    ElevatedButton(
      child: Icon(Icons.add),
      onPressed: () {
        if (jobController.text.isNotEmpty) {
          bucketService.create(jobController.text, user.uid);
        },
      },
    ),
  ],
),

// SingleChildScrollView 위젯은 스크롤을 하나로 만들어 bottom overflow를 해결
SingleChildScrollView(
  child: Padding(
    padding: const EdgeInsets.all(16),
    child: Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(32),
          child: Image.network(
            "https://i.ibb.co/CwzHq4z/trans-logo-512.png",
            width: 81,
          ),
        ),
        TextField(
          decoration: InputDecoration(
            labelText: "이메일",
          ),
        ),
        TextField(
          obscureText: true,
          decoration: InputDecoration(
            labelText: "비밀번호",
          ),
        ),
        Container(
          width: double.infinity,
          margin: EdgeInsets.only(top: 24),
          child: ElevatedButton(
            onPressed: () {},
            child: Text("로그인"),
          ),
        )
      ],
    ),
  ),
),

Material Design widgets Google의 Material Design guidelines에 기반한 위젯
AppBar, BottomNavigationBar, FloatingActionButton

appBar: AppBar(
  centerTitle: true,
  backgroundColor: Colors.xxxx,
  title: Title(
    'text',
    style: TextStyle(
      fontSize: 28,
    ),
  ),
  leading: IconButton(
    icon: Icon(Icon.favorite),
    onPressed: () {
      Navigator.pop(context);
    },
  ),
  actions: [
    TextButton(
      child: Text(
        'text',
        style: TextStyle(
          fontSize: 16,
          color: Colors.xxxx,
        ),
      ),
      onPressed: () {
        Navigator.push(
          context,
          MaterialPageRoute(builder:(context) => FavoritePage(),
        ),
      },
    ),
  ],
)

bottomNavigationBar: BottomNavigationBar(
  items: const <BottomNavigationBarItem>[
    BottomNavigationBarItem(
      icon: Icon(Icons.alarm),
      label: 'Alarm',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.nightlight_round),
      label: 'Sleep',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.settings),
      label: 'Setting',
    ),
  ],
  currentIndex: 0, // 현재 선택된 메뉴
  selectedItemColor: Colors.amber,
),


floatingActionButton: FloatingActionButton(
  onPressed: () {
    print("클릭 되었습니다!");
  },
  child: const Icon(
    Icons.add,
    color: Colors.amber,
  ),
  backgroundColor: Colors.white,
),
Cupertino widgets Apple의 Human Interface Guidelines에 기반한 위젯
CupertinoNavigationBar, CupertinoTabBar
Scrollable widgets 아이템 리스트를 스크롤하게 해주는 위젯
ListView, GridView

// ListView
ListView(
  children: [
    Text("0"),
    Text("1"),
    Text("2"),
    ...
  ]
);

// ListView.builder에 몇 개의 항목을 만들 것이고 몇 번째 항목에는 어떤 View를 그려줄 지 표시
ListView.builder(
  itemCount: 100,
  itemBuilder: (BuildContext ctx, int idx) {
    return Text('Content Number ${idx}');
  },
)

// GridView.builder는 가로, 세로로 몇개씩의 화면을 표시할 지 나타냄
GridView.builder(
  itemCount: bearList!.list!.length, //item 개수
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3, //1 개의 행에 보여줄 item 개수
    childAspectRatio: 1 / 2, //item 의 가로 1, 세로 2 의 비율
    mainAxisSpacing: 10, //수평 Padding
    crossAxisSpacing: 10, //수직 Padding
  ),
  itemBuilder: (BuildContext context, int index) {
    //item 의 반목문 항목 형성
    return Container(
      child: Column(
        children: [
          Image.asset(
            bearList!.list!.elementAt(index).image!,
          ),
          Container(
            height: 50,
            alignment: Alignment.center,
            color: Colors.yellow,
            child: Text(
              '$index',
              style: TextStyle(
                fontSize: 20,
              ),
            ),
          ),
          Expanded(
            child: Container(
              color: Colors.lightGreenAccent,
              alignment: Alignment.center,
              child: Text(
                bearList!.list!.elementAt(index).name!,
                style: TextStyle(
                  fontSize: 20,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  },
),
Interactive widgets 이용자user의 Input에 대응하는 위젯
Button, Checkbox, TextField

// 텍스트 입력을 받을 때 TextField 위젯을 사용
     TextField
        decoration: InputDecoration(
           labelText: "이메일",
        ), //InputDecoration
     ), //TextField

     TextField(
        obscureText: true,
        decoration: InputDecoration(
           labelText: "비밀번호",
        ), //InputDecoration
     ), //TextField

클릭 이벤트를 받는 다양한 Button

// 위로 올라와 있는 듯한 버튼
ElevatedButton(
  onPressed: () {},
  child: Text('Elevated Button'),
), // ElevatedButton 위젯은 라벨과 onPressed 콜백을 가지며, 단독 또는 'ListTile'과 같은 parents 위젯에 포함되어 사용

// 텍스트 버튼
TextButton(
  onPressed: () {},
  child: Text('Text Button'),
), // TextButton 위젯은 라벨과 onPressed 콜백을 가지며, 단독 또는 'ListTile'과 같은 parents 위젯에 포함되어 사용. 버튼을 누를 때 text color가 바뀌고, 언더라인이 생김. 스타일링은 TextButton.styleFrom을 사용. 주로 cancel이나 reset 같은 부차적 액션에 사용

// 아이콘 버튼
IconButton(
  onPressed: () {},
  icon: Icon(Icons.add),
), // IconButton 위젯은 주로 navigation이나 setting 같은 부차적 액션을 위해 사용되며, IconData 객체의 아이콘을 사용. 'padding' property와 'color' property를 사용하며 onPressed 콜백을 가진다. 
GestureDetector and InkWell detect gestures and allow handling of touch events
Animated widgets 애니메이션을 제공해 주는 위젯
AnimatedContainer, AnimatedCrossFade, AnimatedBuilder
Media widgets 미디어를 제공해 주는 위젯
Image, Video
Utility widgets Expanded, Padding, SizedBox

// Padding 위젯은 여백을 추가할 수 있음
Padding
  padding: const EdgeInsets.all(16),
  child: Column(
  ),
),

// SizedBox 위젯은 위젯간 거리를 띄울 때 사용, column에서 쓸경우 width가, Row에서 쓸경우 height가 고정되므로 나머지 하나만 지정
Column( 
  children: [
    SizedBox(height: 100.0,), //Column이기 때문에 width는 Column에 맞춰서 자동으로 적용됨
    Text('How to use Sizedbox'),
    SizedBox(height: 50.0,),
    TextButton(
      style: TextButton.styleFrom(
        backgroundColor: Colors.yellow,
        primary: Colors.red, // foreground
      ),
      onPressed: () { },
      child: Text('press!'),
    )
  ],
),

SingleChildScrollView 위젯은 화면이 넘치지 않고, 스크롤을 할 수 있음

SingleChildScrollView(
  child: Padding(
  ),
),
EdgeInsets은 class로 다양하게 여백을 추가

EdgeInsets.all(8)

EdgeInsets.only(
  left: 8,
  right: 8,
)

EdgeInsets.symmetric(
vertical: 8,
horizontal: 8,
)
 

 

'Coding 배우기' 카테고리의 다른 글

Flutter : 객체, 클래스, 인스턴스, 생성자  (0) 2023.01.15
Flutter : alignment  (0) 2023.01.08
Flutter : Dart 문법  (0) 2023.01.08

관련글 더보기