본문 바로가기

ToyProjects/Flutter 앱 개발

[Flutter] 내 코드로 채택된 ChatGPT 질문/답변(+ ChatGPT로 개발한 후기)

이 {json}으로 dart nested class로 만들어줘
class CertificateResponse {
  final Header header;
  final Body body;

  CertificateResponse({required this.header, required this.body});

  factory CertificateResponse.fromJson(Map<String, dynamic> json) {
    return CertificateResponse(
      header: Header.fromJson(json['header']),
      body: Body.fromJson(json['body']),
    );
  }
}

class Header {
  final String resultCode;
  final String resultMsg;

  Header({required this.resultCode, required this.resultMsg});

  factory Header.fromJson(Map<String, dynamic> json) {
    return Header(
      resultCode: json['resultCode'],
      resultMsg: json['resultMsg'],
    );
  }
}

class Body {
  final List<Item> items;
  final int numOfRows;
  final int pageNo;
  final int totalCount;

  Body({
    required this.items,
    required this.numOfRows,
    required this.pageNo,
    required this.totalCount,
  });

  factory Body.fromJson(Map<String, dynamic> json) {
    var itemsJson = json['items'] as List;
    List<Item> items =
        itemsJson.map((itemJson) => Item.fromJson(itemJson)).toList();
    return Body(
      items: items,
      numOfRows: json['numOfRows'],
      pageNo: json['pageNo'],
      totalCount: json['totalCount'],
    );
  }
}

class Item {
  final String implYy;
  final int implSeq;
  final String qualgbCd;
  final String qualgbNm;
  final String description;
  final String docRegStartDt;
  final String docRegEndDt;
  final String docExamStartDt;
  final String docExamEndDt;
  final String docPassDt;
  final String pracRegStartDt;
  final String pracRegEndDt;
  final String pracExamStartDt;
  final String pracExamEndDt;
  final String pracPassDt;

  Item({
    required this.implYy,
    required this.implSeq,
    required this.qualgbCd,
    required this.qualgbNm,
    required this.description,
    required this.docRegStartDt,
    required this.docRegEndDt,
    required this.docExamStartDt,
    required this.docExamEndDt,
    required this.docPassDt,
    required this.pracRegStartDt,
    required this.pracRegEndDt,
    required this.pracExamStartDt,
    required this.pracExamEndDt,
    required this.pracPassDt,
  });

  factory Item.fromJson(Map<String, dynamic> json) {
    return Item(
      implYy: json['implYy'],
      implSeq: json['implSeq'],
      qualgbCd: json['qualgbCd'],
      qualgbNm: json['qualgbNm'],
      description: json['description'],
      docRegStartDt: json['docRegStartDt'],
      docRegEndDt: json['docRegEndDt'],
      docExamStartDt: json['docExamStartDt'],
      docExamEndDt: json['docExamEndDt'],
      docPassDt: json['docPassDt'],
      pracRegStartDt: json['pracRegStartDt'],
      pracRegEndDt: json['pracRegEndDt'],
      pracExamStartDt: json['pracExamStartDt'],
      pracExamEndDt: json['pracExamEndDt'],
      pracPassDt: json['pracPassDt'],
    );
  }
}

 

json 파싱하는 테스트 코드 알려줘
test('Parsing CertificateResponse from JSON', () {
  const jsonStr = '''
    {
        "header": {
            "resultCode": "00",
            "resultMsg": "NORMAL SERVICE"
        },
        "body": {
            "items": [
                {
                    "implYy": "2023",
                    "implSeq": 101,
                    "qualgbCd": "T",
                    "qualgbNm": "국가기술자격",
                    "description": "국가기술자격 기능사 (2023년도 제101회)",
                    "docRegStartDt": "",
                    "docRegEndDt": "",
                    "docExamStartDt": "",
                    "docExamEndDt": "",
                    "docPassDt": "",
                    "pracRegStartDt": "20230203",
                    "pracRegEndDt": "20230203",
                    "pracExamStartDt": "20230213",
                    "pracExamEndDt": "20230317",
                    "pracPassDt": "20230323"
                },
                {
                    "implYy": "2023",
                    "implSeq": 22,
                    "qualgbCd": "S",
                    "qualgbNm": "국가전문자격",
                    "description": "전문자격 (2023년도 22회 면접)",
                    "docRegStartDt": "20231113",
                    "docRegEndDt": "20231117",
                    "docExamStartDt": "20231211",
                    "docExamEndDt": "20231216",
                    "docPassDt": "20231227",
                    "pracRegStartDt": "",
                    "pracRegEndDt": "",
                    "pracExamStartDt": "",
                    "pracExamEndDt": "",
                    "pracPassDt": ""
                }
            ],
            "numOfRows": 2,
            "pageNo": 1,
            "totalCount": 106
        }
    }
  ''';

  final jsonResponse = jsonDecode(jsonStr);
  final response = CertificateResponse.fromJson(jsonResponse);

  // Check the first item
  final firstItem = response.body.items[0];
  expect(firstItem.implYy, '2023');
  expect(firstItem.implSeq, 101);
  expect(firstItem.qualgbCd, 'T');
  expect(firstItem.qualgbNm, '국가기술자격');​

 

flutter dio 사용해서 api get 요청 보낼 때 parameter에 변수를 사용해서 요청하는 코드 알려줘
import 'package:dio/dio.dart';

// Dio 클라이언트 생성
final dio = Dio();

// API 요청 보내기
Future<Response> fetchData(String query) async {
  final url = 'https://example.com/api/data';
  final response = await dio.get(url, queryParameters: {'q': query});
  return response;
}

 

flutter text size 어떻게 설정해?
Text(
  'Hello, world!',
  style: TextStyle(
    fontSize: 18.0, // 텍스트 크기 설정
  ),
)

 

icon button을 하나는 왼쪽 하나는 오른쪽에 두고 싶어 어떻게 해야돼? 가운데는 title을 위치 시키고 싶어
AppBar(
  leading: IconButton(
    icon: Icon(Icons.menu),
    onPressed: () {
      // 왼쪽 아이콘 버튼을 클릭할 때의 동작
    },
  ),
  actions: [
    IconButton(
      icon: Icon(Icons.search),
      onPressed: () {
        // 오른쪽 아이콘 버튼을 클릭할 때의 동작
      },
    ),
  ],
  title: Text('My App'),
),

 

flutter에서 햄버거 버튼을 눌렀을 때 같은 데이터로 화면에 보여지는 방법만 다르게 하고 싶어
class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

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

class _MyWidgetState extends State<MyWidget> {
  bool _showList = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My App'),
        actions: [
          IconButton(
            onPressed: () {
              setState(() {
                _showList = !_showList;
              });
            },
            icon: Icon(Icons.menu),
          ),
        ],
      ),
      body: _showList ? ListView.builder(...) : GridView.builder(...),
    );
  }
}

 

flutter에서 widget의 body가 isLoading이 false일 때만 보여줄 거고 showCalendar가 true이면 calendarWidget()을 보여주고 false면 listWidget() 을 보여줄 건데 어떻게 구현해야 돼?
class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

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

class _MyWidgetState extends State<MyWidget> {
  bool isLoading = true;
  bool showCalendar = true;

  void loadData() async {
    // load data here
    await Future.delayed(Duration(seconds: 2)); // simulate loading
    setState(() {
      isLoading = false;
    });
  }

  @override
  void initState() {
    super.initState();
    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My App'),
        actions: [
          IconButton(
            onPressed: () {
              setState(() {
                showCalendar = !showCalendar;
              });
            },
            icon: Icon(Icons.calendar_today),
          ),
          IconButton(
            onPressed: () {
              setState(() {
                showCalendar = !showCalendar;
              });
            },
            icon: Icon(Icons.list),
          ),
        ],
      ),
      body: isLoading
          ? Center(
              child: CircularProgressIndicator(),
            )
          : showCalendar
              ? calendarWidget()
              : listWidget(),
    );
  }

  Widget calendarWidget() {
    // show calendar widget here
    return Center(
      child: Text('Calendar Widget'),
    );
  }

  Widget listWidget() {
    // show list widget here
    return Center(
      child: Text('List Widget'),
    );
  }
}

 

_showCalendar가 true일 때 widget dart 파일을 분리하고 싶은데 어떻게 하면 돼?
더보기
_showCalendar
                ? Column(
                    children: [
                      /// Calendar control row.
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          IconButton(
                            icon: const Icon(Icons.arrow_back_ios),
                            onPressed: () {
                              _changeCalendarPage(showNext: false);
                            },
                          ),
                          Text(
                            _monthName,
                            style: const TextStyle(
                                fontSize: 16,
                                color: violet,
                                fontWeight: FontWeight.w600),
                          ),
                          IconButton(
                            icon: const Icon(Icons.arrow_forward_ios),
                            onPressed: () {
                              _changeCalendarPage(showNext: true);
                            },
                          ),
                        ],
                      ),

                      /// Calendar view.
                      Expanded(
                        child: CrCalendar(
                          firstDayOfWeek: WeekDay.sunday,
                          eventsTopPadding: 32,
                          initialDate: _currentDate,
                          maxEventLines: 3,
                          controller: _calendarController,
                          forceSixWeek: true,
                          dayItemBuilder: (builderArgument) =>
                              DayItemWidget(properties: builderArgument),
                          weekDaysBuilder: (day) => WeekDaysWidget(day: day),
                          eventBuilder: (drawer) => EventWidget(drawer: drawer),
                          onDayClicked: _showDayEventsInModalSheet,
                        ),
                      ),
                    ],
                  )
                : Text('아닐 때는 리스트로 보여주기'));
class CalendarWidget extends StatefulWidget {
  const CalendarWidget({
    Key? key,
    required this.monthName,
    required this.currentDate,
    required this.calendarController,
    required this.changeCalendarPage,
    required this.showDayEventsInModalSheet,
  }) : super(key: key);

  final String monthName;
  final DateTime currentDate;
  final CrCalendarController calendarController;
  final Function(bool) changeCalendarPage;
  final Function(DateTime) showDayEventsInModalSheet;

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

class _CalendarWidgetState extends State<CalendarWidget> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            IconButton(
              icon: const Icon(Icons.arrow_back_ios),
              onPressed: () {
                widget.changeCalendarPage(false);
              },
            ),
            Text(
              widget.monthName,
              style: const TextStyle(
                  fontSize: 16,
                  color: violet,
                  fontWeight: FontWeight.w600),
            ),
            IconButton(
              icon: const Icon(Icons.arrow_forward_ios),
              onPressed: () {
                widget.changeCalendarPage(true);
              },
            ),
          ],
        ),
        Expanded(
          child: CrCalendar(
            firstDayOfWeek: WeekDay.sunday,
            eventsTopPadding: 32,
            initialDate: widget.currentDate,
            maxEventLines: 3,
            controller: widget.calendarController,
            forceSixWeek: true,
            dayItemBuilder: (builderArgument) =>
                DayItemWidget(properties: builderArgument),
            weekDaysBuilder: (day) => WeekDaysWidget(day: day),
            eventBuilder: (drawer) => EventWidget(drawer: drawer),
            onDayClicked: widget.showDayEventsInModalSheet,
          ),
        ),
      ],
    );
  }
}

 

response.getItems().sort((a, b) => a.implSeq?.compareTo(b.implSeq)); 여기에서 The return type 'int?' isn't a 'int', as required by the closure's context 이런 오류가 뜨는데 어떻게 해?
이 오류는 implSeq 필드가 nullable 일 수 있다는 의미입니다. 따라서 비교 함수에서 a.implSeq와 b.implSeq가 null 일 수 있다는 것을 고려해야 합니다.

 

flutter list 닫혔다 열렸다 하는 코드 알려줘
class ExpandableListItem {
  ExpandableListItem({
    required this.title,
    required this.content,
    this.isExpanded = false,
  });

  final String title;
  final String content;
  bool isExpanded;
}

class ExpandableList extends StatefulWidget {
  const ExpandableList({Key? key}) : super(key: key);

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

class _ExpandableListState extends State<ExpandableList> {
  final List<ExpandableListItem> _items = [
    ExpandableListItem(
      title: 'Item 1',
      content: 'Content for item 1',
    ),
    ExpandableListItem(
      title: 'Item 2',
      content: 'Content for item 2',
    ),
    ExpandableListItem(
      title: 'Item 3',
      content: 'Content for item 3',
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _items.length,
      itemBuilder: (BuildContext context, int index) {
        final item = _items[index];
        return ExpansionTile(
          title: Text(item.title),
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: Text(item.content),
            ),
          ],
          onExpansionChanged: (bool isExpanded) {
            setState(() {
              item.isExpanded = isExpanded;
            });
          },
          initiallyExpanded: item.isExpanded,
        );
      },
    );
  }
}

 

flutter에서 statefulWidget 파라미터 받아서 생성하는 법 알려줘
class MyWidget extends StatefulWidget {
  final String title; // 파라미터로 전달받을 문자열

  const MyWidget({required this.title, Key? key}) : super(key: key);

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

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.title); // widget.title로 파라미터 사용
  }
}

 

ChatGPT로 개발한 후기

- 구글링 시간이 진짜 훨씬 단축된다.

- 코드를 그대로 쓴다기 보다 그것을 개발하기 위한 키워드나 힌트를 얻을 수 있다.