본문 바로가기

Flutter/10 app Todo with provider

[Flutter] App Todo(with Provider) - 5단계 할일 개수 표시

오늘은 active 상태인 todo 리스트 개수를 표시해보자. 검색기능과 무관하게 순수한 active 개수만 계산한다.

개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 2.10.3

소스코드 위치 - 06_Active_count · mike-bskim/todo_test (github.com)

 

Release 06_Active_count · mike-bskim/todo_test

 

github.com

 

동작 영상은 아래와 같다.

 

 

todo_active_count.dart 생성 - 활성상태인 리스트의 개수를 화면 상단 우측에 표시한다.

 

import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:todo_test/provider/providers.dart';

class TodoActiveCountState extends Equatable {
  final int todoActiveCount;

  const TodoActiveCountState({
    required this.todoActiveCount,
  });

  factory TodoActiveCountState.init() {
    return const TodoActiveCountState(todoActiveCount: 0);
  }

  @override
  List<Object> get props => [todoActiveCount];

  @override
  String toString() =>
      'TodoActiveCountState(todoActiveCount: $todoActiveCount)';

  TodoActiveCountState copyWith({
    int? todoActiveCount,
  }) {
    return TodoActiveCountState(
      todoActiveCount: todoActiveCount ?? this.todoActiveCount,
    );
  }
}

class TodoActiveCount with ChangeNotifier {
  TodoActiveCountState _state = TodoActiveCountState.init();
  TodoActiveCountState get state => _state;

  void update(TodoList todoList) {
    final int newTodoActiveCount =
        todoList.state.todos.where((todo) => !todo.completed).toList().length;
    _state = _state.copyWith(todoActiveCount: newTodoActiveCount);
    notifyListeners();
  }
}

 

main.dart 수정 - proxyprovider 추가

 

return MultiProvider(
  providers: [
    ChangeNotifierProvider<TodoList>(create: (context) => TodoList()),
    ChangeNotifierProvider<TodoFilter>(create: (context) => TodoFilter()),
    ChangeNotifierProvider<TodoSearch>(create: (context) => TodoSearch()),
    ChangeNotifierProxyProvider3<TodoFilter, TodoSearch, TodoList,
        FilteredTodos>(
      create: (context) => FilteredTodos(),
      update: (
        BuildContext context,
        TodoFilter todoFilter,
        TodoSearch todoSearch,
        TodoList todoList,
        FilteredTodos? filteredTodos,
      ) =>
          filteredTodos!..update(todoFilter, todoSearch, todoList),
    ),
    
    // 새로 추가된 proxyprovider
    ChangeNotifierProxyProvider<TodoList, TodoActiveCount>(
      create: (context) => TodoActiveCount(),
      update: (
        BuildContext context,
        TodoList todoList,
        TodoActiveCount? todoActiveCount,
      ) =>
          todoActiveCount!..update(todoList),
    )
  ],
  child: MaterialApp(
    title: 'TODOS',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: const TodosScreen(),
  ),
);

 

providers.dart 수정 - "export 'todo_active_count.dart';" 추가

 

export 'todo_list.dart';
export 'todo_filter.dart';
export 'filtered_todos.dart';
export 'todo_search.dart';
export 'todo_active_count.dart';

 

todo_screen.dart 수정 -  watch 추가, const 키워드 위치 변경

 

class TodoHeader extends StatelessWidget {
  const TodoHeader({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        const Text(
          'TODO',
          style: TextStyle(fontSize: 40.0),
        ),
        Text(
        // watch 추가
          '${context.watch<TodoActiveCount>().state.todoActiveCount} items left',
          style: const TextStyle(
            fontSize: 20.0,
            color: Colors.redAccent,
          ),
        ),
      ],
    );
  }
}

 

 

 

 

[참고자료] udemy - Flutter Provider Essential 코스 (Korean)