Flutter

회기역 지하철 시간 타이머 앱 - 4 (마무리)

HAHAKO 2023. 5. 4. 13:26

이제 http로 데이터까지 다 받아왔고

데이터에서 시간을 받아오고 그 시간에서 현재시간을 뺀 값을 표시만 하면 된다.

 

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:math';
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart' as xml;
import 'package:xml/xml.dart';
import 'package:flutter_test/flutter_test.dart';

void main() => runApp(MyApp());


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

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


class Rightnow extends StatefulWidget {

  @override
  _RightnowState createState() => _RightnowState();
}

class _RightnowState extends State<Rightnow> {

  @override
  void initState() {

    super.initState();

    Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() {

      });
    });
  }

  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Container(
        child: GetTime(),
        color: Colors.black,
      ),
    );
  }
}

class GetTime extends StatelessWidget {

  var now = DateTime.now();

  Future<List<Subway>> fetchXmlData() async {
    final response = await http.get(Uri.parse('http://swopenapi.seoul.go.kr/api/subway/6a684e6f49646d733130364c4b74466e/xml/realtimeStationArrival/1/10/회기'));
    final document = xml.parse(response.body);
    final items = document.findAllElements('row');

    var subway = <Subway>[];
    items.forEach((node) {
      subway.add(Subway.fromXml(node));
    });
      
    return subway;
  }
  

  
  @override
    Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
          color: Colors.black,
          child: Center(
            child : FutureBuilder(
            future: fetchXmlData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasData) {
                  String text = "";
                  text += '${snapshot.data![9].recptnDt} ';
                  text += '${snapshot.data![1].recptnDt}';
                  dynamic firstlinesec = text.substring(37,39);
                  dynamic firstlinemin = text.substring(34,36);
                  dynamic firstlinehour = text.substring(31,33);
                  
                  dynamic khlinesec = text.substring(17,19);
                  dynamic khlinemin = text.substring(14,16);
                  dynamic khlinehour = text.substring(11,13);

                  firstlinesec = int.parse(firstlinesec);
                  firstlinemin = int.parse(firstlinemin);
                  firstlinehour = int.parse(firstlinehour);
                  khlinesec = int.parse(khlinesec);
                  khlinemin = int.parse(khlinemin);
                  khlinehour = int.parse(khlinehour);
                  
                  var firstlinetime = Duration(hours: firstlinehour, minutes: firstlinemin, seconds: firstlinesec);
                  var khlinetime = Duration(hours: khlinehour, minutes: khlinemin, seconds: khlinesec);
                  var nowtime = Duration(hours: now.hour, minutes: now.minute, seconds: now.second);

                  var firstline = firstlinetime.inSeconds - nowtime.inSeconds;
                  var khline = khlinetime.inSeconds - nowtime.inSeconds;
                  
                  return Text(
                    '1호선 청량리행\n$firstline\n경의중앙선 청량리행\n$khline',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      fontFamily: 'Roboto',
                      fontSize: 50,
                      color: Colors.white,
                    ),
                  );
                } else {
                    return Text('No data');
                }
              } else {
                  return Text('Loading...');
              }
            },
          ),
        ),
      ),
    );
  }
}


class Subway {
  String? rowNum;
  String? selectedCount;
  String? totalCount;
  String? subwayId;
  String? updnLine;
  String? trainLineNm;
  String? statnFid;
  String? statnTid;
  String? statnId;
  String? statnNm;
  String? ordkey;
  String? subwayList;
  String? statnList;
  String? barvlDt;
  String? btrainNo;
  String? bstatnId;
  String? recptnDt;
  String? arvlMsg2;
  String? arvlMsg3;
  String? arvlCd;

  Subway({
      this.rowNum,
      this.selectedCount,
      this.totalCount,
      this.subwayId,
      this.updnLine,
      this.trainLineNm,
      this.statnFid,
      this.statnTid,
      this.statnId,
      this.statnNm,
      this.ordkey,
      this.subwayList,
      this.statnList,
      this.barvlDt,
      this.btrainNo,
      this.bstatnId,
      this.recptnDt,
      this.arvlMsg2,
      this.arvlMsg3,
      this.arvlCd});

    factory Subway.fromXml(XmlElement xml){
      return Subway(
        rowNum : PutElement.searchResult(xml, 'rowNum'),
        selectedCount : PutElement.searchResult(xml, 'selectedCount'),
        totalCount : PutElement.searchResult(xml, 'totalCount'),
        subwayId : PutElement.searchResult(xml, 'subwayId'),
        updnLine : PutElement.searchResult(xml, 'updnLine'),
        trainLineNm : PutElement.searchResult(xml, 'trainLineNm'),
        statnFid : PutElement.searchResult(xml, 'statnFid'),
        statnTid : PutElement.searchResult(xml, 'statnTid'),
        statnId : PutElement.searchResult(xml, 'statnId'),
        statnNm : PutElement.searchResult(xml, 'statnNm'),
        ordkey : PutElement.searchResult(xml, 'ordkey'),
        subwayList : PutElement.searchResult(xml, 'subwayList'),
        statnList : PutElement.searchResult(xml, 'statnList'),
        barvlDt : PutElement.searchResult(xml, 'barvlDt'),
        btrainNo : PutElement.searchResult(xml, 'btrainNo'),
        bstatnId : PutElement.searchResult(xml, 'bstatnId'),
        recptnDt : PutElement.searchResult(xml, 'recptnDt'),
        arvlMsg2 : PutElement.searchResult(xml, 'arvlMsg2'),
        arvlMsg3 : PutElement.searchResult(xml, 'arvlMsg3'),
        arvlCd : PutElement.searchResult(xml, 'arvlCd'),
      );
    }
}

class PutElement{
  static String searchResult(XmlElement xml, String key){
    return xml.findAllElements(key).map((e) => e.text).isEmpty? "" :xml.findAllElements(key).map((e)=> e.text).first;
  }
}

전체코드이다.

 

일단 rowNum 10번째가 경중선, rowNum 1번째가 1호선 청량리행 데이터라서 (xml 파일 예시를 보면 알 수 있음)

data[9]와 data[1]을 일단 넣어주고

String 처리를 통해 시간, 분, 초를 불러온다.

그리고 Duration method를 이용해서 차를 구하고 화면에 표시하면 끝난다.

 

위는 구현 영상이다.

보니까 -초도 나오는데, 서울시에서 그렇게 정확한 데이터를 제공하지는 않는 것 같다.

그래도 쓸모가 있을 것 같아 친구 맥북으로 앱으로 만들어서 써먹어야겠다.

근데 하루에 1000번 request 제한 있어서 나밖에 못쓸 것 같다.