ABOUT ME

Today
Yesterday
Total
  • 25일차 과제[2] - Todo 활용
    카테고리 없음 2023. 2. 28. 20:24

    1. 다음의 공개된 API를 분석하고, 클래스를 활용하여 적용 후 해야할 일을 보여주는 앱을 다음과 같이 만드시오. https://jsonplaceholder.typicode.com/todos

    예제

    • 반드시 Todo 클래스를 만들고 Serialization을 진행할 수 있도록 하시오.
    • AppBar는 다음의 조건을 따라 만들도록 하시오
      1. Blur 효과를 넣어 body의 내용이 흐릿하게 보여질 수 있도록 디자인하시오.
      2. Actions에는 다음의 기능이 포함되어있는 아이콘을 제작하시오
        • Filter 아이콘 :
          • 클릭시 아래서 필터를 설정할 수 있도록 시트 위젯이 켜진다.
          • 필터가 적용되면 화면에 보이는 데이터의 종류가 바뀐다.
          • (필터선택시 아래에서 올라오는 안내문구는 선택사항임)
        • Refresh 아이콘 :
          • 클릭시 네트워크에 데이터를 한 번 더 요청하여 리스트에 재적용한다.
    • 각 Post를 보여주는 Widget은 다음의 조건을 따라 만들도록 하시오
      1. 완료된 상태의 Post라면, 초록색 배경에 체크버튼의 아이콘이 보여지도록 한다.
      2. Dismissable 위젯을 활용하여 옆으로 슬라이드 했을 때, 리스트에서 사라지도록 한다.
        1. 추가적으로, Dismissable 위젯의 key 속성이 의미하는 바를 정리하시오.
    • 제공되는 소스코드를 활용할 수 있도록 하시오.
      • widget/filter_bottom_sheet.dart
        • 필터 아이콘 누를 시 하단에 출력되는 위젯입니다.
        • enum에 대해 학습을 따로 진행하는 것을 추천드립니다.
        import 'package:flutter/material.dart';
        
        enum TodoFilter { all, completed, incompleted }
        
        class FilterBottomSheet extends StatefulWidget {
          const FilterBottomSheet(
              {Key? key, required this.filter, required this.onApply})
              : super(key: key);
          final TodoFilter filter;
          final Function(TodoFilter) onApply;
        
          @override
          State<FilterBottomSheet> createState() => _FilterBottomSheetState();
        }
        
        class _FilterBottomSheetState extends State<FilterBottomSheet> {
          onApply(TodoFilter filter) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('Filter applied: $filter'),
              ),
            );
            widget.onApply(filter);
            Navigator.pop(context);
          }
        
          @override
          Widget build(BuildContext context) {
            return Container(
              padding: const EdgeInsets.all(16),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ListTile(
                    title: const Text('All'),
                    trailing: Checkbox(
                      value: widget.filter == TodoFilter.all,
                      onChanged: (value) {
                        if (value == true) onApply(TodoFilter.all);
                      },
                    ),
                  ),
                  ListTile(
                    title: const Text('Completed'),
                    trailing: Checkbox(
                      value: widget.filter == TodoFilter.completed,
                      onChanged: (value) {
                        if (value == true) onApply(TodoFilter.completed);
                      },
                    ),
                  ),
                  ListTile(
                    title: const Text('InCompleted'),
                    trailing: Checkbox(
                      value: widget.filter == TodoFilter.incompleted,
                      onChanged: (value) {
                        if (value == true) onApply(TodoFilter.incompleted);
                      },
                    ),
                  ),
                ],
              ),
            );
          }
        }
        
      • widget/todo_card.dart(model 폴더에 todo클래스를 만들어놓을 것)
    import 'package:flutter/material.dart';
    
    import '../model/todo.dart';
    
    class TodoCard extends StatelessWidget {
      const TodoCard({super.key, required this.todo});
      final Todo todo;
    
      @override
      Widget build(BuildContext context) {
        return Dismissible(
          key: Key(todo.id.toString()),
          child: Container(
            margin: const EdgeInsets.all(8),
            decoration: BoxDecoration(
              color: todo.completed ? Colors.green.shade100 : null,
              border: todo.completed
                  ? Border.all(
                      color: Colors.green,
                    )
                  : null,
              borderRadius: BorderRadius.circular(8),
            ),
            child: ListTile(
              title: Text(
                todo.title,
                style: TextStyle(
                  color: todo.completed ? Colors.green : null,
                  fontWeight: FontWeight.bold,
                ),
              ),
              trailing: todo.completed
                  ? const Icon(
                      Icons.check_circle,
                      color: Colors.green,
                    )
                  : null,
            ),
          ),
        );
      }
    }

     

     

     

    main.dart

    import 'package:assigment25second/mainpage.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MainPage(),
        );
      }
    }

    mainpage.dart

    import 'dart:ui';
    
    import 'package:assigment25second/model/todo.dart';
    import 'package:assigment25second/widget/filter_bottom_sheet.dart';
    import 'package:assigment25second/widget/todo_card.dart';
    import 'package:flutter/material.dart';
    import 'package:dio/dio.dart';
    
    class MainPage extends StatefulWidget {
      const MainPage({super.key});
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      List<Todo> todos = [];
      TodoFilter todoFilter = TodoFilter.all;
    
      readTodos() async {
        var dio = Dio();
        var url = 'https://jsonplaceholder.typicode.com/todos';
        var res = await dio.get(url);
        if (res.statusCode == 200) {
          var data = List<Map<String, dynamic>>.from(res.data);
          setState(() => todos = data.map((e) => Todo.fromMap(e)).toList());
        }
      }
    
      @override
      void initState() {
        super.initState();
        readTodos();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            extendBodyBehindAppBar: true,
            appBar: AppBar(
                backgroundColor: Colors.transparent,
                foregroundColor: Colors.black,
                elevation: 0,
                flexibleSpace: ClipRRect(
                  child: BackdropFilter(
                    filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
                    child: Container(),
                  ),
                ),
                title: Text('Todo App'),
                actions: [
                  IconButton(
                      onPressed: (() {
                        showModalBottomSheet(
                            context: context,
                            builder: ((context) => FilterBottomSheet(
                                filter: todoFilter,
                                onApply: ((value) {
                                  setState(() => todoFilter = value);
                                }))));
                      }),
                      icon: Icon(Icons.filter_list)),
                  IconButton(
                      onPressed: (() {
                        readTodos();
                      }),
                      icon: Icon(Icons.refresh))
                ]),
            body: ListView.builder(
                itemCount: filterMaker(todos).length,
                itemBuilder: ((context, index) {
                  return TodoCard(todo: filterMaker(todos)[index]);
                })));
      }
    
      List<Todo> filterMaker(List<Todo> value) {
        switch (todoFilter) {
          case TodoFilter.all:
            return value;
          case TodoFilter.completed:
            return value.where((element) => element.completed == true).toList();
          case TodoFilter.incompleted:
            return value.where((element) => element.completed == false).toList();
        }
      }
    }

    FutureBuild사용해서 풀고있는데 계속 에러나와서 강의보고 따라해봤습니다.. 강의내용은 이해가 되긴했는데 난이도가 있네요.. FutureBulid사용해서 제가 하던대로 다시 풀어보겠습니다.

     

    widget/todo_card.dart와 widget/filter_bottom_sheet.dart은 안건드림! 코드는 이해가는데 만들라하면 못만들거같네요

     

    제가 풀어서 다시 제출하겠습니다

     

    결과

Designed by Tistory.