[ 앱 개발자 도전기 : 크로스플랫폼_Flutter & Dart ] 기본 개념 정리-上

0

App_Dev : Flutter

목록 보기
4/5
post-thumbnail

[ 앱 개발자 도전기 : 크로스플랫폼_Flutter & Dart ] 기본 개념 정리-上.

▽FLutter 기본 개념 정리-上.

목  차

1. 플러터의 설계-컨셉
2. 플러터의 기본 위젯
3. 화면이동 이벤트
4. Stateless & Stateful
5. 

Ⅰ. 플러터의 설계-컨셉.

🩻 . Widget : 모든 것은 위젯이다.

플러터에서 가장 중요한 개념은 "위젯"이라는 개념입니다.

Flutter프레임워크에서는 모든 것이 '위젯'으로 조합하여 만들어진 화면으로 구성됩니다.

플러터의 화면 구조는 여러 위젯들이 트리-형태로 구성되어있습니다.

class MyWidget extends Widget{
	String title; // 프로퍼티(멤버)
    String description;
    int count'
    Widget child; // 자식 위젯
    
    MyWidget({this.title, this.description, this.count}); // 생성자
    
    @override
    Widget build(BuildContext context){
    	return ...;
    }
}

가장 상위 위젯으로는
'상태'를 가지는 'StatefulWidget'과 상태를 가지지 않는 'StatelessWidget'의 두가지 종류가 있습니다.

  • 'StatelessWidget' : 말 그대로 변화가 없는 위젯,
    그러므로 초기값을 지정하기만 하면 만들어지는 화면을 말합니다.

  • 'StatefulWiget' : 계속 상태가 변화함을 의미합니다.
    이 말은 화면에 표시되는 내용도 변경된다는 것과 같습니다.

    • 이러한 '화면표시'는 '상태관리'라는 개념을 활용해서 화면을 갱신합니다.

각 위젯의 'Life cycle'은 다음과 같습니다.

🩻 'setState'와 'didUpdateWidget'의 차이점.

🩻 setState

  • setState는 상태변경을 트리거하고,
    이에 따라서 FLutter 프레임워크가 '위젯'을 다시 빌드하도록 요청하는데 사용됩니다.

  • StaefulWidget'에서만 사용가능하며,
    setState를 호출하면 위젯의 build메서드가 다시 호출되어 UI를 업데이트 합니다.

.
.

☆ Flutter의 setState와 React에서 사용하는 useState 비교해보기.

  • Flutter의 setState
    • 구현 방식.
      • StatefulWidget 내에서만 사용 가능합니다.
      • setState는 동기적으로 작동하며, '콜백'을 호출한 후 '위젯 리빌드'를 예약합니다.
      • 위젯의 생명주기 동안 변경될 수 있는 상태를 관리합니다.
class _ExampleState extends State<Example> {
  int count = 0;
  
  void increment() {
    setState(() {
      count++;
    });
  }
}
  • React의 useState
    • 구현 방식.
      • 함수형 컴포넌트에서 사용되는 'Hook'입니다.
      • 배열 구조분해를 통해 상태값과 setter 함수를 반환합니다.
      • 비동기적으로 작동하며, 상태 업데이트가 즉시 반영되지 않습니다.
function Counter() {
  const [count, setCount] = useState(0);
  
  const increment = () => {
    setCount(count + 1);
  };
}
  • 주요 차이점.
  • 사용 시 고려사항.
    • Flutter의 setState는 작은 규모의 로컬 상태 관리에 적합.
    • React의 useState는 여러 상태를 독립적으로 관리 가능.
    • 두 방식 모두 복잡한 상태관리가 필요한 경우 다른 상태관리 솔루션 고려필요.
      • React는 redux 혹은 zustand 등 // Flutter는 Bloc, GetX, Provider 등

🩻 didUpdateWidget

  • didUpdateWidet'은 부모 위젯이 변경될 때 호출되는 메서드입니다.

  • StaefulWidget'의 부모가 새로운 구성을 전달하면 ( ex: 부모 위젯이 다시 빌드되면 )
    didUpdateWidget이 호출됩니다.

  • 이 메서드는 주로 부모 위젯에서 전달받은 새로운 구성을 처리하거나,
    상태를 적절하게 업데이트하는 데 사용됩니다.

🩻 . State: 반응성(Reactive) 구현

  • "상태(State)"는 말 그대로 어떤 상태에 대한 값을 저장하는 변수를 가리킵니다.

  • 'State'는 어떤 이벤트가 발생한다면, 다른 상태값으로 바뀌게 됩니다.

  • 'State'는 정말 다양한 방법으로 사용되는데, 로그인 여부나 찜하기 등 정말 다양한 상태가 사용.

🩻 . Stream : 필요한 데이터가 있으면 찾아간다.

  • 스트림(Stream)은 흐름이라는 뜻으로,
    시간이 지남에 따라 발생하는 데이터의 흐름이라고 이해할 수 있습니다

  • 데이터를 불러오는 데 시간이 오래 걸리거나,
    지속적으로 데이터를 받아야 하는 경우 스트림을 통해 구현하게 됩니다

  • 스트림을 통해 받는 데이터들은 언제 수신이 완료되는 지 명확히 알 수 없다는 단점이 있기 때문에, 데이터를 생산하는 영역과 사용하는 영역을 구분해 구현되며,
    말 그대로 '구독'해 변화를 확인할 수 있습니다

Ⅱ. 플러터의 기본 위젯.

🩻 Container : 가장 기초가 되는 위젯.

:: Container 위젯은 큰 상자처럼 위젯을 담는 역할을 하며 Padding(여백)을 설정 가능합니다.

🩻 Container의 옵션.

  • EdgeInsets : 여백을 주기 위해 위젯을 사용하며 [all, froLTRB, only, symmetric ] 방식이 있습니다.

  • color : 상자의 배경색을 설정합니다.

  • width, height : 너비와 높이를 설정합니다.

Container(
	child: Text('Hello, Flutter!'),
    padding: EdgeInsets.all(30),
    color: Colors.blue,
    height: 300,
    width: 300,
)

🩻 image : 이미지 넣기.

image는 이미지를 넣기 위한 위젯입니다.

로컬에 저장한 이미지를 사용하기 위해선 pubspec.yaml 파일에 이미지를 등록해야 합니다.

또한, 크기 지정 시 설정 크기와 원본의 비율이 다를 경우에 원본을 지키는 쪽으로 설정됩니다.

assets:
  - images/flutter_logo.png  #예시

🩻 image의 옵션.

  • Image.asset : 로컬 내에 있는 이미지를 불러오는 방법.

  • Image.network : 인터넷의 이미지를 불러오는 방법.

  • width, height : 너비와 높이를 설정합니다.

Image.asset('images/flutter_logo.png')
Image.network('https://~')

🩻 Text : 텍스트 위젯.

문자열을 나타낼 수 있는 위젯으로, child를 사용하지 않고 문자열을 집어넣으면 화면이 출력됩니다.

TextStyle 위젯을 통해, 문자열을 꾸밀 수 있습니다.

🩻 TextStyle 옵션.

  • fontSize, color, fontweight 등
Text(
	'Hello, Text Widget!',
    style: TextStyle(
    	fontSize: 25,
        color: Colors.purple,
        fontFamily: '지정',
        fontWeight: FontWeight.w700,
    ),
)

🩻 Column, ROW

  • 화면에 위젯을 배치할 때 도움을 주는 위젯으로,
    플러터에는 대표적으로 {Column, Row, ListView, Stack}이 있습니다.

  • Column은 위에서 아래로(↓), Row는 좌에서 우로(→) 위젯들을 배치합니다.

    • 여러 위젯들을 감싸기 때문에, 'children'을 사용합니다.

🩻 Column, Row의 옵션.

  • mainAxisAlignment : 위에서 아래로 가는 방향에서, 어떤 기준으로 정렬할 지 결정(Row는 반대)
    • center, start, end, spaceEvenly, spaceAround, spaceBetween 등
  • crossAxisAlignment : 왼쪽에서 오른쪽으로 가는 방향에서, 어떤 기준으로 정렬할 지 결정
    • center, start, end 등

🩻 ListView : 스크롤 할 수 있는 화면 만들기.

  • 'Column'이나 'Row'는 화면을 벗어날 만큼 많은 양의 데이터가 있으면 'Button Overflowed'가 발생합니다.

  • 'ListView'는 많은 양의 데이터가 들어와도 스크롤이 가능한 화면을 구성하게 해줍니다.

🩻 ListView의 옵션.

  • scrollDirection : 스크롤 방향을 지정해, 좌우 방향으로도 사용이 가능합니다.
    • Axis / horizontal
  • ListView는 builder라는 함수를 활용해 만드는 방법도 존재합니다.
ListView.builder(
	itemCount: 50,
    itemBuilder: (BuildContext context, int index) {
    	return Text(
        	'$index' + ' Text',
            style: TextStyle(fontSize: 25),
        );
	}
),

🩻 Stack : 위젯 위에 위젯 쌓기.

  • 'Stack' 위젯은 위젯 위에 위젯을 쌓고 싶을 때 사용합니다.
    • 좀 더 정밀하게 만들기 위해
      위치를 특정하게 지정할 수 있는 'Positioned'라는 위젯의 도움을 받기도 합니다.
Stack(
   children: [
    Image.asset('images/flutter_logo.png'),
    Positioned(
      left: 0,
      bottom: 0,
      child: Image.network(
        'https://~',
        width: 100,
        height: 100,
      ),
    ),
  ],
),

-->> Positioned 위젯으로 감싸고, left와 bottom값을 0으로 설정했는데,
이는 좌측방향으로 0만큼, 하단 방향으로 0만큼 떨어지게끔 배치하라는 설정입니다.

🩻 Button : TextButton, ElevatedButton, OutlinedButton

:: Flutter에는 IconButton까지 4종류의 버튼이 존재합니다.

Center(
  child: Column(
   mainAxisAlignment: MainAxisAlignment.center,
   children: [
   	 // Text 위젯만 존재
     TextButton(onPressed: (){}, child: Text('Text Button'),),
     Padding(padding: EdgeInsets.all(20)),
     // 배경색이 칠해져 있는 상태의 버튼
     ElevatedButton(onPressed: (){}, child: Text('Elevated Button'),),
     Padding(padding: EdgeInsets.all(20)),
     // 테두리가 그려져 있는 버튼
     OutlinedButton(onPressed: (){}, child: Text('Outlined Button'),),
     Padding(padding: EdgeInsets.all(20)),
     // icon()을 인자로 받아 아이콘 형태의 버튼
     IconButton(onPressed: (){}, icon: Icon(Icons.star),),
     Padding(padding: EdgeInsets.all(20)),
   ],
  ),
 ),

Ⅲ . 화면이동 이벤트.

대부분의 앱은 여러개의 화면을 가지고, 버튼 등을 활용해 해당 화면으로 이동하게 됩니다.

🩻 화면 이동(Navigator.push)

  • 모든 화면 전환 관련 이벤트는 'Navigator'라는 위젯을 통해 처리됩니다.

  • Navigator를 활용하면 화면을 '특정 화면'으로 이동하거나,
    '이전 화면'으로 돌아가는 기능을 구현 가능합니다.

ElevatedButton(
	onPressed: () {
		Navigator.of(context).push(
			MaterialPageRoute(
				builder: (BuildContext context) => SecondScreen(),
			),
		);
	},
	child: Text('Go to Second Screen'),
),

-> Navigator.of(context)로 시작하는데, 이는 현재 위젯인 'Scaffold' 화면에서 이동하겠다는 코드.
-> 여기에 'Push'로 화면을 쌓아서 이동을 구현합니다.
-> MaterialPageRoute를 통해 'Navigator'가 이동할 경로를 지정해줍니다.

🩻 화면 뒤로 가기(Navigator.pop)

ElevatedButton(
	onPressed: () {
		Navigator.of(context).pop();
	},
	child: Text('Go to Second Screen'),
),

Navigator.of(context)까지는 push와 비슷하지만, .pop()으로 끝나는게 다릅니다.

🩻 화면 이동할 때 데이터 전달하기.

  • 화면 클래스의 생성자를 활용해서, 객체를 생성할 때 객체 내의 변수에 해당 인자 값을 저장 가능합니다.

-> 이를 활용해, 화면을 이동할 때 데이터를 넘겨주는 기능을 구현 가능합니다.

🩻 클래스 인자 전달 및 전달받은 인자 사용하기.

네비게이션 로직.

ElevatedButton(
	onPressed: () {
		Navigator.of(context).push(
			MaterialPageRoute(
				builder: (BuildContext context) => SecondScreen(
                	screenData: 'Data from FirstScreen',
                ),
			),
		);
	},
	child: Text('Go to Second Screen'),
),

◆위 코드의 기본 구조.
: ElevatedButton은 Material Design 스타일 버튼 위젯으로, 그림자가 있는 돌출된 형태의 버튼 생성.

  • 주요 속성.

    • 'onPressed' : 버튼이 눌렸을 때 실행되는 콜백 함수를 정의.
    • 'child' : 버튼 내부에 표시될 위젯을 지정.
  • 화면 이동.

    • 'Navigator.of(context)'는 현재 화면의 네비게이션 컨텍스트를 가져옵니다.
    • 'push'메서드는 새로운 화면을 네비게이션 스택에 추가.
    • 'MaterialPageRoute'는 플랫폼별 화면 전환 애니메이션을 제공.
  • 데이터 전달.
    + 'screenData' 파라미터를 통해 첫 번째 화면에서 두 번째 화면으로 데이터를 전달.
    + 'SecondScreen' 위젯은 이 데이터를 생성자를 통해 받아서 사용 가능.
    .
    .

SecondScreen 위젯 구현.

class SecondScreen extends StatelessWidget {
 final String screenData;
 
 const SecondScreen({Key? key, required this.screenData}) : super(key: key);
 
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: Text('Second Screen')),
     body: Center(
       child: Text(screenData),
     ),
   );
 }
}

Ⅳ. Stateless & Stateful

  • StatelessWidget은 위에서 계속 사용한 위젯으로, 상태가 없는 위젯입니다.
    • 제목이나 이미지와 같이 변하지 않는 위젯들은 StatelessWidget으로 구현 가능합니다.
  • StatefulWidget은 상태를 포함한 위젯입니다.
    • 상태를 선언 가능하고, 변화가 감지되었을 때 변화에 대한 이벤트를 수행합니다.
import 'package:flutter/material.dart';

class FirstScreen extends StatefulWidget {

  @override
  State<FirstScreen> createState() => _FirstScreenState(); // 1번
}

class _FirstScreenState extends State<FirstScreen> { // 2번
  
  @override
  void initState() { // 3번
    // TODO: implement initState
    super.initState();
  }
  
  @override
  Widget build(BuildContext context) { // 4번
    return Scaffold(
      appBar: AppBar(),
      body: Center(),
    );
  }
  
  @override
  void dispose() { // 5번
    // TODO: implement dispose
    super.dispose();
  }
}
  1. createState()라는 메소드를 사용하여 Statef를 생성 합니다
    StatefulWidget은 그 내부에서 사용할 State를 생성하는 것으로 그 역할을 다 합니다

  2. State 또한 플러터 내부에서 선언된 클래스인데, 이를 상속받아FirstScreenState라는 클래스를 만들었습니다
    앞에
    를 붙이는 것은 관례적인 표현입니다

  3. 앞서 생성한 State를 초기화하는 단계로, 필수적이진 않습니다
    super.initState()를 통해 부모 클래스의 initState() 메소드를 함께 실행합니다

  4. StatelessWidget과 동일합니다

  5. dispose()는 위젯이 사라질 때 실행되는 단계로, 역시 필수적이진 않습니다

0개의 댓글

관련 채용 정보