ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Flutter - 코로나 어플 만들기 [3]
    Flutter 2021. 1. 24. 10:44
    728x90
    반응형

    API 요청해서 XML 파싱하기

     

    코로나데이터를 클래스로 만들어 준다.

    class CovidItem {
      String accDefRate;
      String accExamCnt;
      String accExamCompCnt;
      String careCnt;
      String clearCnt;
      String deathCnt;
      String decideCnt;
      String examCnt;
      String resutlNegCnt;
      String seq;
      String stateDt;
      String stateTime;
      String updateDt;
      String createDt;
    
      CovidItem(
          {this.accDefRate,
          this.accExamCnt,
          this.accExamCompCnt,
          this.careCnt,
          this.clearCnt,
          this.deathCnt,
          this.decideCnt,
          this.examCnt,
          this.resutlNegCnt,
          this.seq,
          this.stateDt,
          this.stateTime,
          this.updateDt,
          this.createDt});
    }

     

    MainPageState에 받아올 데이터를 저장할 변수를 정의한다.

    class MainPageState extends State<MainPage> {
      XmlDocument CovidStatusXML;
      CovidItem covidItem = new CovidItem();
        ...

     

    appBar에 추가해준다.

            title: Text("코로나 현황"),
            centerTitle: true,
            actions: [
              IconButton(
                icon: Icon(Icons.sync),
                onPressed: () async {
    
                  var dateNow = DateTime.now();
                  var dateStr = formatDate(dateNow, [yyyy,mm,dd]).toString();
    
                  var url =
                      "http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19InfStateJson?ServiceKey=ServiceKey&pageNo=1&numOfRows=10&startCreateDt="+dateStr+"&endCreateDt="+dateStr;
                  var response = await http.get(url);
    
                  CovidStatusXML = XmlDocument.parse(response.body);
                  final items = CovidStatusXML.findAllElements('item');
                  setState(() {
                    items.forEach((element) {
                      covidItem = CovidItem(
                        accDefRate: element.getElement('accDefRate').text,
                        accExamCnt: element.getElement('accExamCnt').text,
                        accExamCompCnt: element.getElement('accExamCompCnt').text,
                        careCnt: element.getElement('careCnt').text,
                        clearCnt: element.getElement('clearCnt').text,
                        deathCnt: element.getElement('deathCnt').text,
                        decideCnt: element.getElement('decideCnt').text,
                        examCnt: element.getElement('examCnt').text,
                        resutlNegCnt: element.getElement('resutlNegCnt').text,
                        seq: element.getElement('seq').text,
                        stateDt: element.getElement('stateDt').text,
                        stateTime: element.getElement('stateTime').text,
                        updateDt: element.getElement('updateDt').text,
                        createDt: element.getElement('createDt').text,
                      );
                    });
                  });
                },
              )
            ],

     

     

    오늘 날짜를 가져와 'yyyymmdd' 형태로 변환한다.

    var dateNow = DateTime.now();
    var dateStr = formatDate(dateNow, [yyyy,mm,dd]).toString();

     

    오늘 날짜의 데이터를 가져오도록 url을 만든다. (ServiceKey는 공공데이터에서 발급받은 Key로 입력한다.)

    var url = "http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19InfStateJson?ServiceKey=ServiceKey&pageNo=1&numOfRows=10&startCreateDt="+dateStr+"&endCreateDt="+dateStr;

     

    GET방식으로 데이터를 요청하고 response를 받는다.

    var response = await http.get(url);

     

    받은데이터를 XML로 변환하고 CovidItem으로 만들어 covidItem에 저장한다.

                CovidStatusXML = XmlDocument.parse(response.body);
                  final items = CovidStatusXML.findAllElements('item');
                  setState(() {
                    items.forEach((element) {
                      covidItem = CovidItem(
                        accDefRate: element.getElement('accDefRate').text,
                        accExamCnt: element.getElement('accExamCnt').text,
                        accExamCompCnt: element.getElement('accExamCompCnt').text,
                        careCnt: element.getElement('careCnt').text,
                        clearCnt: element.getElement('clearCnt').text,
                        deathCnt: element.getElement('deathCnt').text,
                        decideCnt: element.getElement('decideCnt').text,
                        examCnt: element.getElement('examCnt').text,
                        resutlNegCnt: element.getElement('resutlNegCnt').text,
                        seq: element.getElement('seq').text,
                        stateDt: element.getElement('stateDt').text,
                        stateTime: element.getElement('stateTime').text,
                        updateDt: element.getElement('updateDt').text,
                        createDt: element.getElement('createDt').text,
                      );
                    });
                  });

    findAllElements: 이름이 'item'인 element들을 전부 가져온다.

    setState(): covidItem에 값을 넣고 해당변수를 사용한 모든 Widget을 업데이트할 수 있다.

     

     

    Widget에 적용하기

    child: ListView(
                  children: [
                    Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      mainAxisSize: MainAxisSize.max,
                      children: [
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisSize: MainAxisSize.max,
                          children: [
                            Expanded(
                              child: _CovidItemPanel(
                                title: "확진자",
                                value: covidItem.decideCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                            Expanded(
                              child: _CovidItemPanel(
                                title: "격리해제",
                                value: covidItem.clearCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Expanded(
                              child: _CovidItemPanel(
                                title: "검사진행",
                                value: covidItem.examCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                            Expanded(
                              child: _CovidItemPanel(
                                title: "사망자",
                                value: covidItem.deathCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Expanded(
                              child: _CovidItemPanel(
                                title: "치료중인 환자",
                                value: covidItem.careCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                            Expanded(
                              child: _CovidItemPanel(
                                title: "결과 음성",
                                value: covidItem.resutlNegCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 32,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Expanded(
                              child: _CovidItemPanel(
                                title: "누적검사",
                                value: covidItem.accExamCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 32,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                            Expanded(
                              child: _CovidItemPanel(
                                title: "누적 검사 완료",
                                value: covidItem.accExamCompCnt ?? "0",
                                textStyle: TextStyle(
                                  fontSize: 32,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Expanded(
                              child: _CovidItemPanel(
                                title: "누적 환진률",
                                value: ((double.parse(covidItem.accDefRate ?? "0")*100).round()/100).toString(),
                                textStyle: TextStyle(
                                  fontSize: 36,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                            Expanded(
                              child: _CovidItemPanel(
                                title: "등록일",
                                value: covidItem.createDt ?? "yyyy.mm.dd",
                                textStyle: TextStyle(
                                  fontSize: 18,
                                  color: Theme.of(context).accentColor,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    )
                  ],
                ),

     

    아래와 같이 covidItem을 통해 데이터를 받아 각 Panel에 적용될 수 있도록 설정한다.

    value: covidItem.decideCnt ?? "0",

     

    728x90
    반응형

    댓글

Designed by Tistory.