Study/Development

[개발일지] flutter 앱개발 2주차

titann 2022. 9. 12. 23:53

<스파르타코딩 flutter 강의 수강일지>

 

2주차: 사용자가 보는 화면 만들기

1. Flutter Widget

1) Stateless vs Stateful

Stateless: 상태변화 X -> 새로고침 X Stateful: 상태변화 O -> 새로고침 O

*setState()는 Stateful에서 동작한다.

VSC에서 st 까지만 입력하면, Stateful Widget과 Stateless Widget의 기본 프리셋이 자동완성 된다.

/// Stateless Widget

class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
  }
}


/// Stateful Widget
class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    
  }
}

 

2) 기본 위젯: Text / Container / Icon / Image

// Text
Text(
  '텍스트 위젯',
  style: TextStyle(
    fontSize: 35, // 폰트 크기
    fontWeight: FontWeight.bold, // 폰트 두께
    color: Colors.amber, // 폰트 색상
  ),
),

// Container
Container(
  width: 200, // 폭
  height: 200, // 높이
  color: Colors.pinkAccent, // 박스 색상
  child: Text("I Love Flutter!"), // 자식 위젯
  
  padding: EdgeInsets.all(20), // 박스 안쪽 영역
  margin: EdgeInsets.all(50), // 박스 바깥 영역
  alignment: Alignment.topLeft, // child 정렬
),

// Material Icon
Icon(
  Icons.home,
  color: Colors.blue,
  size: 50,
),

// Cupertino Icon
Icon(
  CupertinoIcons.house,
  color: Colors.pink,
  size: 50,
),

// Image Network
Image.network(
    'https://i.ibb.co/CwzHq4z/trans-logo-512.png',
    width: 150,
  ),

 

*EdgeInsets (Padding/Margin)

// 전방위
EdgeInsets.all(8)

// 특정 방위만 적용
EdgeInsets.only(
  left: 8,
  right: 8,
)

//수직, 수평으로 적용
EdgeInsets.symmetric(
	vertical: 8,
	horizontal: 8,
)

 

*BoxDecoration

Container(
  width: 200,
  height: 200,
  // color : Colors.amber, // decoration와 함께 사용 불가
  decoration: BoxDecoration(
    color: Colors.amber, // decoration 안에 color를 활용해주세요.
    borderRadius: BorderRadius.circular(50), // 모서리를 둥글게
    border: Border.all(color: Colors.blue, width: 5), // 테두리
    boxShadow: [
      BoxShadow(
        // 그림자 효과
        color: Colors.grey.withOpacity(0.7), // 투명도 70% 회색
        spreadRadius: 5, // 퍼짐 효과
        blurRadius: 7, // 뭉갬 효과
        offset: Offset(5, 5), // 그림자를 우측 5 아래 5만큼 이동
      ),
    ],
  ),
);

 

Material Icon 모아보기

https://fonts.google.com/icons?selected=Material+Icons 

 

Material Symbols and Icons - Google Fonts

Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.

fonts.google.com

 

Cupertino Icon 모아보기

https://shuuji3.xyz/flutter-packages/third_party/packages/cupertino_icons/

 

Cupertino Icons 1.0.0 Gallery

 

shuuji3.xyz

 

 

3) 레이아웃(Layout) 위젯: Scaffold / Column / Row / Stack / SingleChildScrollView

*SingleChildScrollView와 Listview.builder는 같이 쓰지 않는다.

 

Scaffold

Scaffold(
	appBar: AppBar(), // 상단 바
	body: Text(), //화면 중앙에 가장 큰 면적
	bottomNavigationBar: BottomNavigationBar(), //하단 바
	floatingActionButton: FloatingActionButton(), //우측 하단
),

AppBar 구성

Column / Row

Column(
  children: [
    // 자식 위젯들
    Text("위젯1"),
    Text("위젯2"),
  ],
  
  // 세로 방향에 대한 크기
  mainAxisSize: MainAxisSize.max, // 부모를 가득
  mainAxisSize: MainAxisSize.min, // 자식 크기만큼
  
  // 세로 방향 정렬
  mainAxisAlignment: MainAxisAlignment.center, // 중앙
  mainAxisAlignment: MainAxisAlignment.start,  // 시작
  mainAxisAlignment: MainAxisAlignment.end, // 끝
  mainAxisAlignment: MainAxisAlignment.spaceBetween, // 양 끝에 배치하고 등분
  mainAxisAlignment: MainAxisAlignment.spaceAround, // 균등하게 나누고 공간의 절반을 뒤에
  mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 등분
  
  // 가로 방향 정렬
  crossAxisAlignment: CrossAxisAlignment.center, // 중앙
  crossAxisAlignment: CrossAxisAlignment.start, // 시작
  crossAxisAlignment: CrossAxisAlignment.end, // 끝
  crossAxisAlignment: CrossAxisAlignment.stretch, // 늘려 가득 채움
),

// Column과 가로 세로 반대
Row(
  children: [
    // 자식 위젯들
    Text("위젯1"),
    Text("위젯2"),
  ],
),

 

Stack: 쌓아 올림

Stack(
  children: [ // 자식 위젯들
    Text("위젯1"),
    Text("위젯2"),
  ],
),

 

SingleChildScrollView: 위젯이 스크린보다 클 때, 스크롤 할 수 있도록 함.

SingleChildScrollView(
  child: Container(height: 10000), // 자식 위젯
),

 

3. 텍스트 입력: TextField

TextField(
  autofocus: true, // 자동 포커스
  onChanged: (text) {
    // 텍스트 변경시 실행되는 함수
  },
  onSubmitted: (text) {
    // Enter를 누를 때 실행되는 함수
  },
),

 

 

4. 클릭 이벤트: Button

// 위로 올라와 있는 듯한 버튼
ElevatedButton(
  onPressed: () {
    print("Elevated Button 클릭");
  },
  child: Text('Elevated Button'),
),

// 텍스트 버튼
TextButton(
  onPressed: () {
    print("Text Button 클릭");
  },
  child: Text('Text Button'),
),

// 아이콘 버튼
IconButton(
  onPressed: () {
    print("Icon Button 클릭");
  },
  icon: Icon(Icons.add),
),

 

5. 화면 이동: Navgator.push / pop

// 다음 페이지로 이동
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SecondPage()), // 이동하려는 페이지
);

// 현재 화면 종료
Navigator.pop(context); // 종료

 

6. 공백 위젯: Spacer, Sizedbox, Divider

// 가로 세로 일정 간격 줄 때
SizedBox(height: 20),
SizedBox(width: 20),

// 사이 공간을 꽉 채울 때
Spacer()

// 구분선 넣을 때
Divider()

 

 

2. 실습과제

ClipRRect: 모서리를 둥글게

ClipRRect(
  borderRadius: BorderRadius.only(
    topLeft: Radius.circular(8),
    topRight: Radius.circular(8),
  ),
  child: Image.network(
    imageUrl,
    fit: BoxFit.fitHeight,
    height:
        MediaQuery.of(context).size.width * 0.4,
  ),
),

 

GestureDetector: 탭, 더블탭 등 제스처에 함수 할당

  GestureDetector(
    onTap: () {
      DefaultTabController.of(context)?.animateTo(0);
    }, // 탭할 때 함수 실행
    child: Column(
      children: [
        Icon(Icons.person, color: Colors.white),
        Text(
          '라이브러리',
          style: TextStyle(color: Colors.white),
        ),
      ],
    ),
  ),

 

SafeArea: 노치 혹은 상단 스테이터스 바 영역 비워줌

SafeArea(
  child: Scaffold(
    appBar: AppBar(),
  ),
);

 

Positioned: 위치 조정

  Stack(
    children: [
      Positioned(
        left: 28.0,
        top: 20.0,
        child: UserProfileImage(
          imageURL: room.speakers[1].imageUrl,
          size: 48,
        ),
      ),
      UserProfileImage(
        imageURL: room.speakers[0].imageUrl,
        size: 48,
      )
    ],
  ),

 

TabBar / TabBarView: 탭하여 다른 내용 보여줌

// AppBar에 넣음
TabBar(
            tabs: [
              Tab(text: "Chats"),
              Tab(text: "Requests"),
            ],
          ),
        ),
        
        
// Body에 넣음
TabBarView(
  children: [
    ListView.builder(
      itemCount: backChannelRoomsList.length,
      itemBuilder: (context, index) {
        return BackChannelRoomCard(
            backChannelRoom: backChannelRoomsList[index]);
      },
    ),
    Center(
      child: Text(
        "👍 You're all good!\nYou don't have any new\nmessage requests.",
        textAlign: TextAlign.center,
      ),
    ),
  ],
),

 

ListTile: 리스트 형식의 타일

ListTile(
    leading: FlutterLogo(size: 72.0),
    title: Text('Three-line ListTile'),
    subtitle: Text(
      'A sufficiently long subtitle warrants three lines.'
    ),
    trailing: Icon(Icons.more_vert),
    isThreeLine: true,
  ),

ListTitle 구성

 

 

반응형