Notice
Recent Posts
Recent Comments
Link
«   2025/12   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

Milan Dev

#Flutter. EPL 일정 앱 개인 프로젝트 ep.3 선택된 팀 화면 구현 본문

Flutter

#Flutter. EPL 일정 앱 개인 프로젝트 ep.3 선택된 팀 화면 구현

jjjuyoa 2024. 1. 19. 23:25

개인적인 사정으로 작업 시간을 할당하기가 힘들어서 늦게 화면개발을 했습니다..ㅠㅠ

 

제가 이번에 구현한건 팀 선택시 경기일정을 리스트로 보여주는 화면입니다.

 

 

해당 팀을 선택하면 선택된 화면의 앞으로의 경기일정을 보여줍니다.

 

api는 해당 팀의 경기 일정을 모두 가져오는데 이를 위해 팀을 선택했을때 해당 팀의 team id 파라미터를 가져와 1라운드 부터 38라운드의 경기 일정을 가져옵니다. 

가져온 경기 일정중에 경기 시작시간이 이미 현재 시간을 넘은 경기들은 다음과 같이 처리하여 아직 시작하지 않은 경기들만 모아두었습니다. 

FutureBuilder<TeamMatchInfoModel>(
                future: futureTeamMatchInfoModel,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return CircularProgressIndicator();
                  } else if (snapshot.hasError) {
                    return Text("오류가 발생했습니다.");
                  } else {
                    List<Widget> matchWidgets = [];
                    for (var match in snapshot.data!.matches) {
                      // utcDate를 DateTime 객체로 변환
                      DateTime matchDate = DateTime.parse(match.utcDate);
                      //현재 시간 이후의 경기만 추가
                      if (DateTime.now().difference(matchDate).inDays <= 0) {
                        matchWidgets.add(MatchInfo(matches: match));
                      }
                    }
                    return Column(
                      children: matchWidgets,
                    );
                  }
                },
              )

다음과 같이 현재 시간을 가져와 utcDate(경기 시작 시간)와 비교하여 아직 진행하지 않은 경기만 불로오도록 했습니다. 

 

다음은 알림을 받을 경기들을 선택할 수 있도록 스위치를 만드는 작업입니다. 스위치는 bool 자료형을 value값으로 받아 false 이면 꺼져있고 true 면 켜진 상태입니다. 

이제 스위치를 누르면 상태가 변경되어 화면에 스위치가 꺼졌는지 켜졌는지 바로바로 렌더링하도록 합니다. 

주의할 점은 StatefulWidget을 사용해야 즉각적으로 바뀐 상태에 따라 화면을 렌더링 할 수 있습니다. 화면이 상태에 따라 변경된다면 꼭 StatelessWidget 말고 StatefulWidget을 사용해야 합니다!

class _MatchInfoState extends State<MatchInfo> {
  bool isChecked = false; // 1.매치 스위치 상태값 
  late int matchId;

// 2. 값을 저장하는 함수
  Future<void> setSwitchState(int key, bool value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setBool(key.toString(), value);
  }

// 3. 값을 불러오는 함수
  Future<bool> getSwitchState(int key) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool value = prefs.getBool(key.toString()) ?? false;
    return value;
  }

// 4. 2번에 value 값을 세팅
@override
  void initState() {
    super.initState();
    matchId = widget.matches.id;
    getSwitchState(matchId).then((value) {
      setState(() {
        isChecked = value;
      });
    });
  }





////////////////
//////////////// 5. 스위치가 사용되는 부분 

Switch(
                          value: isChecked,
                          onChanged: (value) async {
                            setState(() {
                              isChecked = value!;

                              print("check the switch!!");
                            });
                            await setSwitchState(matchId, isChecked);
                          }),

 

스위치를 활성화 할 때 조심해야 할 것은 각 스위치의 key 값을 설정하는 것입니다. 처음에 key 값을 설정하지 않고 코드를 작성해서 상태를 하나의 스위치를 누르면 앱을 다시 실행했을때 모든 스위치가 켜져있는 불상사가 발생했었습니다..

스위치 각각의 상태를 알 수 있도록 matchId를 key값으로 사용하여 확인했습니다.

 

1. 스위치는 기본적으로 false(꺼짐) 상태를 갖도록 합니다.

2. 스위치를 누르면 4번 후 shared_preferences 에 상태값을 저장. 이로인해 앱이 꺼저있어도 로컬에 스위치 상태를 갖고 있을 수 있음 

3. 앱이 다시 실행되거나 화면이 변경되어도 다시 설정된 상태값을 로컬에서 가져와 렌더링

4. setState를 통해 isChecked 값을 현재 값의 NOT 타입으로 변경하여 설정

 

이로인해 스위치의 상태를 처리 할 수 있었습니다.

 

state를 다루는건 아마 리액트 를 다룬적이 있는 분들이라면 꽤 익숙하게 보이실 거라 생각합니다. 저 또한 리액트에서 사용한 state 이용방법 덕분에 무리없이 상태를 다룰 수 있었습니다.

 

다음엔 스위치가 켜진 경기에 대한 알림을 받아오는 작업으로 돌아오겠습니다.

봐주셔서 감사합니다!