커뮤니티
포인트
쿠폰
내 강의실
국비 신청 내역
증명서
계정
로그아웃
학습 질문
개발 일지
나의 활동
답변 완료
강의에서 다루지 않았던 내용 질문드려도 되나요?
[왕초보] 플러터(Flutter)로 시작하는 앱개발 종합반
기타
북마크
손*령
댓글
4
추천
0
조회수
17
조회수
17
답변 완료

* 겪고 있는 문제 상황을 최대한 자세하게 작성해주세요.

* 문제 해결을 위해 어떤 시도를 해보았는지 구체적으로 함께 알려주세요.


안녕하세요.

종합반 수강 후 개인 앱을 만들어보고 싶어서 개발 중인데요,

코드를 아무리 봐도 모르겠고... 질문할만한 곳을 찾지 못 해 이곳을 찾아왔습니다...

(강의에서 알려주셨던 커뮤니티는 닫힌 것 같아요ㅜㅜ)


열품타 같은 타이머 어플을 만들고 싶은데요. 실행 조건은 아래와 같습니다.

  1. 과목별로 나누어서 시간을 기록
  2. 앱을 재실행했을 때 이전에 등록한 과목과 기록한 시간 불러오기
  3. 하루에 여러 번에 걸쳐 기록할 경우, 각각의 시작시간, 종료시간을 모두 기록
  4. 매일 공부시간 초기화
  5. 아래 화면처럼 공부 기록을 볼 수 있도록 DB에 저장


상태관리를 위해 service 파일을 만들었고, 그 안에서 돌아가는 코드 중 일부이고요.

현재 서버는 구축하지 않아서 Hive 방식으로 로컬에 저장되도록 해둔 상태입니다.


에뮬레이터에서 타이머가 움직이긴 하는데, 타이머를 중지한 후 다시 시작할 때, 저장된 이전 시간에서 정확히 이어지지 않고 잘못된 값으로 시작합니다. 

이전 값이 중복으로 더해지는 것 같습니다.


예를 들면,

새로 과목을 추가하여 00:00:00으로 시작.

3초 실행 후 정지하면 00:00:03이 아니라 00:00:06으로 저장됨.

다시 시작버튼을 누르면 00:00:10으로 시작됨.

3초 실행 후 정지하면 00:00:19로 저장됨.


이런식으로 값이 이상하게 저장되고 있는 것으로 보입니다.


타이머 경과 시간은 Hive를 사용해 저장하고 있고,

저장된 이전 시간(`previousElapsedMilliseconds`)을 기반으로 타이머를 이어서 작동시키고자 합니다.


수업 외 내용이지만 의견 주시면 너무 감사드리겠습니다..

구글링도 해보고 GPT 한테도 물어봤는데 도무지 모르겠습니다...ㅜㅜ

답변 어려우실 경우 이런 문제를 물어볼 수 있는 사이트라도 소개 부탁드립니다.🙏




▼만들고자 하는 화면

스파르타 즉문즉답





  final Box<Subject> _subjectBox = Hive.box<Subject>('subjects');
  final Box<Map> _dailyRecordsBox =
      Hive.box<Map>('dailyStudyRecords'); // 날짜별 기록 저장
  final Box<int> _elapsedTimesBox = Hive.box<int>('elapsedTimes'); // 타이머 상태 저장


  List<Subject> get subjectList => _subjectBox.values.toList();

// 타이머 상태 관리용 변수
  final Map<String, Stopwatch> _stopwatches = {}; // 과목별 Stopwatch
  final Map<String, Timer> _timers = {}; // 과목별 Timer
  final Map<String, DateTime> _currentSessionStartTimes = {}; // 과목별 시작 시간


  // 초기 데이터 로드 (Hive에서 불러오기)
  void loadSubjectsFromHive() {
    if (!_elapsedTimesBox.isOpen) {
      print("Error: 'elapsedTimes' Box is not open");
      return;
    }
    for (var subject in subjectList) {
      final elapsedMilliseconds =
          _elapsedTimesBox.get(subject.id) ?? 0; // null 처리
      if (elapsedMilliseconds > 0) {
        _stopwatches[subject.id] = Stopwatch(); // Stopwatch 초기화
        print(
            "Loaded Stopwatch for ${subject.name} with $elapsedMilliseconds ms");
      }
    }


    Future.microtask(() {
      notifyListeners();
    });
  }

void startTimer(String id) {
  final subject = _subjectBox.get(id);
  if (subject != null) {
    if (!_stopwatches.containsKey(id)) {
      _stopwatches[id] = Stopwatch(); // Stopwatch 초기화
    }
    final stopwatch = _stopwatches[id]!;
    final previousElapsedMilliseconds = _elapsedTimesBox.get(id) ?? 0;


    if (!stopwatch.isRunning) {
      stopwatch.start();


      // 기존 타이머 취소
      _timers[id]?.cancel();


      // 새로운 타이머 시작
      _timers[id] = Timer.periodic(Duration(seconds: 1), (timer) {
        final currentElapsedMilliseconds = stopwatch.elapsedMilliseconds;
        final totalElapsedMilliseconds =
            previousElapsedMilliseconds + currentElapsedMilliseconds;


        final formattedTime =
            _formatDuration(Duration(milliseconds: totalElapsedMilliseconds));


        updateTimeSpent(id, formattedTime);
        _elapsedTimesBox.put(id, totalElapsedMilliseconds);
      });
    }
  }
}


void stopTimer(String id) {
  final subject = _subjectBox.get(id);
  if (subject != null) {
    final stopwatch = _stopwatches[id];
    if (stopwatch != null && stopwatch.isRunning) {
      stopwatch.stop();
      _timers[id]?.cancel();


      final currentElapsedMilliseconds = stopwatch.elapsedMilliseconds;
      final previousElapsedMilliseconds = _elapsedTimesBox.get(id) ?? 0;
      final totalElapsedMilliseconds =
          previousElapsedMilliseconds + currentElapsedMilliseconds;


      _elapsedTimesBox.put(id, totalElapsedMilliseconds);


      final formattedTime =
          _formatDuration(Duration(milliseconds: totalElapsedMilliseconds));


      updateTimeSpent(id, formattedTime);
    }
  }
}


String getTotalTimeSpent() {
  int totalSeconds = subjectList.fold<int>(0, (sum, subject) {
    final parts = subject.timeSpent.split(':').map(int.parse).toList();
    return sum + (parts[0] * 3600) + (parts[1] * 60) + parts[2];
  });


  final hours = totalSeconds ~/ 3600;
  final minutes = (totalSeconds % 3600) ~/ 60;
  final seconds = totalSeconds % 60;


  return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}



취소
 공유
취소
댓글 0
댓글 알림
나의얼굴