본문 바로가기
취미노트/코딩공부

[flutter] 10 효율적인 데이터 관리 1, List

by 복습쟁이 2024. 8. 28.
반응형

 

 

 

학습을 위한 선행준비 : 데이터가 들어있는 장표 만들어보기

 

가. 앱 기본골격 셋팅

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: WorkoutTrackerPage(),
    );
  }
}

class WorkoutTrackerPage extends StatefulWidget {
  const WorkoutTrackerPage({super.key});

  @override
  State<WorkoutTrackerPage> createState() => _WorkoutTrackerPageState();
}

class _WorkoutTrackerPageState extends State<WorkoutTrackerPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Workout Tracker Page'),
      ),
    );
  }
}

 

[메인함수 MyApp] - [MyApp STL Widget : MaterialApp, home : Page] - [Page STF Widget : Scaffold] 구조를 만들고

appBar를 간단히 타이틀은 텍스트 넣어서 세팅해주자

 

 

 

나. '오늘의 운동' 카드 만들기

오늘의 운동이라는 타이틀이 가운데 있고,

좌측에는 운동명 / 우측에는 운동 횟수가 있는 화면을 만들어보고자 한다.

 

(1) 

'카드'를 만들어야 하니, 바디에 카드를 주었다.

색상은 그레이에 셰이드를 200주어서 좀 밝은 느낌을 주었다.

 

내용물이 세로로 채워질 예정이니 Column을 주고,

일단 들어가야 될 텍스트들을 넣어보았다.

그런데 이대로는 안될 것 같다. 세로로 여백이 너무 길다.

 

(2)

Card를 Column으로 Wrap함으로써, 일단 세로 여백이 긴 문제는 해결이 되었다.

Card 전체의 범위까지만 Column이 표시되기 때문이다.

하지만, 아직 카드를 가로로 길게 늘려야 하는 문제가 있다.

 

 

(3)

'오늘의 운동' 이하 배치되는 컨텐츠를 가로로 배치되도록 Row로 방향을 틀었다.

이제 두 텍스트 간의 거리만 멀어지면 어느 정도 원하는 그림이 나올 것 같다.

 

(4)

Alignment 속성을 Row아래에 주어서, 두 텍스트 간의 공간을 띄웠다. 

Row를 여러개 복사함으로써 아래로 운동의 종류와 숫자를 원하는 만큼 추가가 가능하다.

 

(5) 

 

여백, 언더라인 등 꾸밈으로써 장표를 마무리 해 보았다.

하지만 매 번 운동명과 목표 수량이 바뀌는 프로그램을 만들고 싶다면 어떻게 해야 할까?

 

 

1. [dart] Collection - List

바뀌는 값을 저장하는 것은? 변수이다.

변수를 각각 지정하자니, 운동명 목표회수 마다 해줘야 되면 너무 처리할 것이 많다.

하나의 변수에 그룹화된 것을 묶을 수 있는데, 이를 콜렉션 그룹이라고 한다.

이 중 대표적인 것이 List.

List 데이터순서O, 중복O
Map 데이터순서X, key-value조합, key는 중복불가
Set 데이터순서X, 중복X

 

- List의 특징 -

  • 리스트는 대괄호[ ] 를 이용해 표현
  • 리스트 타입은 여러 값들을 순서대로, 순차적으로 저장한다
  • index 라는 숫자 값으로 저장된 값에 접근한다
  • 반복이 가능하다(iterable) -> for 또는 while 같은 loop에 넣어 동작하기 좋은 강력한 기능
  • list에는 여러 값을 넣을 때, type을 섞어 넣을 수 있다
  • list 내에 list를 중첩해서 넣을 수 있다

 

List는 List라는 타입을 가진 변수라고 생각하자.

 

List = vehicle[];          //List 선언, vehicle 변수는 dynamic임

 

List<String> = vehicle[];    //지정될 타입을 명시적으로 찍어 선언하기도 가능(지정된 타입만 넣을 수 있음)

 

  List<String> vehicle=['car','bike','ship','airplane','kickboard','scooter'];  //String만 저장될 수 있는 vehicle 변수
    print(vehicle[0]);            // 결과 : car , 참고로 인덱스는 int타입 고정이며 개발자가 변경 불가
    print(vehicle[3]);           // 결과 : airplane
    vehicle[4] = 'wagon';     // 결과 : kickboard를 wagon으로 변경

 

 

- List의 기능 - 

 

예를 들어, List testList 가 있을 때,

testList.length : 길이(개수가 몇개인가)

testList.first : 첫번째값

testList .last : 마지막값

testList .add[값] : 리스트 안에 값 추가

testList .clear[ ] : 리스트 안에 들어있는 값들 삭제

testList.isEmpty[ ] : 값이 0인지 체크 후 T/F 반환

testList.contains[값] : 원하는 값이 있는지 체크 후 T/F반환

 

 

- 리스트를 더하는 방법 -

예를 들어 

listA = [1,2,3]

listB = [0,0,0]일 때

 

(1) List listC = listA + listB -> [1,2,3,0,0,0]   // 더하기 오퍼레이터

(2) List listD=[5,5,5,...listB] -> [5,5,5,0,0,0]  // spread operator(...)으로 확장

 

2. [dart] Collection - Map

  • 중괄호{  }로 표현한다
  • key와 value로 구성된다. 여기에는 모든 형태 데이터 타입 가능
  • key는 중복 불가(value는 가능)
  • 타 언어에서 hash, dictionary 등으로 불리기도 한다.
  • Map의 크기는 요소들의 개수에 따라 자유롭게 조정이 가능하다. 크기가 고정되어있지 않음.

 

예제

 

Map vehicle={};     // vehicle라는 변수에 빈 값을 할당한 Map

 

Map<String.int>=vehicle={'car':4, 'bike':2, 'ship':0, 'airplane':3};  // key는 String, value는 int를 준 값. 선언과 동시에 초기화도 가능.

 

print(vehicle[car]);  //  4라는 값이 나온다. key를 통해 value값에 접근 가능.

vehicle['wagon']=4; // wagon이라는 새로운 key에 4라는 value 할당

 

Map answer={'car':4, 'bike':2, 'ship':0, 'airplane':3, 'kickboard':Car(), Vehicle():true};

value 4 2 0 3 Car() true
key car bike ship airplane kickboard Vehicle

 * Map은 밸류와 키 값 모두 타입의 제한 없음. (반면, List의 인덱스는 무조건 int)      

 

- Map의 기능 - 

 

Map vehicle={'car':4, 'bike':2, 'ship':0, 'airplane':3};  가 있을 때,

vehicle.values : value만 출력해준다 [car, bike, ship, airplane]

vehicle.containsKey[car]  : 주어진 key가 있는지 확인, T/F반환 

vehicle.containsValue[3]  : 주어진 value가 있는지 확인, T/F반환 

vehicle.remove['bike'] : 주어진 key를 가진 item을 삭제한다

vehicle.addAll[{'kickboard':2}]; : 주어진 item을 추가한다

vehicle.clear[]; : 모든 아이템을 삭제한다

 

 

3. [dart] Collection - Set

  • 중괄호{  }로 표현한다.
  • 중복 불가.
  • 반복 가능 => loop에 넣을 수 있다

예제

Set answer = {'good',12,true,[],{}};    // set은 마치 List처럼 value만 나열한다. 다이나믹한 값 가능.

Set<String> vehicle={'car', 'bike', 'ship', 'airplane'}   // 제네릭 타입 부여 가능

 

print(vehicles.contains('bike'));   // 메소드를 이용하여 값에 접근. bike를 포함하는가 여부 -> true가 출력됨.

vehicles.elementAt(3);    // airplane

 

* 활용도 상 Set보다는 List와 Map 먼저 이해

 

 

4. 콜렉션 구조를 App에 적용해보기

안드로이드 스튜디오로 돌아가서, 오늘의 운동이 내일의 운동이 되거나 주말의 운동이 될 때를 생각해보자.

즉, 운동명과 운동횟수는 모두 변하는 값이다. 하나하나 변경하기에는 비효율이니, 콜렉션으로 모아보자.

 

class _WorkoutTrackerPageState extends State<WorkoutTrackerPage> {
  List<String> workoutName=['싯업','친업','스쿼트'];
  List<int> workoutGoal=[50,15,100];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Workout Tracker Page'),
      ),
      body: Column(
        children: [
          Card(
            color: Colors.grey.shade200,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                children: [
                  Text(
                    '오늘의 운동',
                    style: TextStyle(fontSize: 19),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text('1.${workoutName[0]}'),
                      Text('${workoutGoal[0]}'),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text('2.${workoutName[1]}'),
                      Text('${workoutGoal[1]}'),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text('3.${workoutName[2]}'),
                      Text('${workoutGoal[2]}'),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

1. STF위젯에서 변수를 만들 때, 보편적으로 class와 빌드 메소드 사이에 정의한다.

2. 리스트를 만들텐데, 운동명으로 만들것이므로 String으로 정의

3. 초기값은 '싯업', '친업', '스쿼드'로 준다. 리스트는 이미 순서가 있으므로 넘버링은 뺀다.

4. int를 주고 목표운동값을 적용해준다.

5. 데이터로 처리한 변수를 오늘의 운동에 출력하면 된다.

6. Text 안에서 싯업 등 운동명들을 ${workoutName[0]}부터 넣을 수 까지로 변경한다.

7. Text 안에서 목표운동횟수들을 ${workoutGoal[0]}부터 넣을 수 까지로 변경한다.

8. 일단 핫 리로드를 하면 잘 안나올 수 있다. 적용이 불가능한 범위이기 때문. 핫 리스타트 필요.

9. 내일의 운동, 주말의 운동에 따라서 리스트 안의 데이터만 바꿔주면 된다.

 

728x90
반응형

댓글