ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • provider 다루기
    프로그래밍 공부 메모/flutter 2022. 6. 10. 22:06

    context.read<> / consumer<> 의 차이점

    provider의 상태를 관리하는 변수의 값이 변경되어 해당 화면을 다시 그릴 경우 consumer<>,

    해당 위젯이 변경될 부분이 없으며 화면이 바뀔 내용이 없을고 하지만 provider pool(service)에 있는 요소를

    1회성으로 클래스에 접근하고 싶을 때 context.read <>(); 사용

     

    항상 notifyListners()를 호출하여 갱신이 된 걸 알려줘야 한다

     

    [ 메인 페이지 ]

    import 'package:bucket_provider/bucket_service.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(
              create: ((context) => BucketService()),
            ),
          ],
          child: const MyApp(),
        ),
      );
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: HomePage(),
        );
      }
    }
    
    /// 버킷 클래스
    class Bucket {
      String job; // 할 일
      bool isDone; // 완료 여부
    
      Bucket(this.job, this.isDone); // 생성자
    }
    
    /// 홈 페이지
    class HomePage extends StatelessWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Consumer<BucketService>(
          builder: (context, bucketservice, child) {
            //BucketService bucketservice = BucketService()
    
            List<Bucket> bucketList = bucketservice.bucketList;
            return Scaffold(
              appBar: AppBar(
                title: Text("버킷 리스트"),
              ),
              body: Center(
                child: ListView.builder(
                  itemCount: bucketList.length,
                  itemBuilder: (context, index) {
                    var bucket = bucketList[index];
                    return ListTile(
                      title: Text(bucket.job),
                      trailing: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () {
                          bucketservice.deletBucket(index);
                        },
                      ),
                      onTap: () {
                        bucket.isDone = !bucket.isDone;
                        bucketservice.updateBucket(bucket, index);
                      },
                    );
                  },
                ),
              ),
              floatingActionButton: FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () {
                  // + 버튼 클릭시 버킷 생성 페이지로 이동
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (_) => CreatePage()),
                  );
                },
              ),
            );
          },
        );
      }
    }
    
    /// 버킷 생성 페이지
    class CreatePage extends StatefulWidget {
      const CreatePage({Key? key}) : super(key: key);
    
      @override
      State<CreatePage> createState() => _CreatePageState();
    }
    
    class _CreatePageState extends State<CreatePage> {
      // TextField의 값을 가져올 때 사용합니다.
      TextEditingController textController = TextEditingController();
    
      // 경고 메세지
      String? error;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("버킷리스트 작성"),
            // 뒤로가기 버튼
            leading: IconButton(
              icon: Icon(CupertinoIcons.chevron_back),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                // 텍스트 입력창
                TextField(
                  controller: textController,
                  autofocus: true,
                  decoration: InputDecoration(
                    hintText: "하고 싶은 일을 입력하세요",
                    errorText: error,
                  ),
                ),
                SizedBox(height: 32),
                // 추가하기 버튼
                SizedBox(
                  width: double.infinity,
                  height: 48,
                  child: ElevatedButton(
                    child: Text(
                      "추가하기",
                      style: TextStyle(
                        fontSize: 18,
                      ),
                    ),
                    onPressed: () {
                      // 추가하기 버튼 클릭시
    
                      String job = textController.text;
                      if (job.isEmpty) {
                        setState(() {
                          error = "내용을 입력해주세요."; // 내용이 없는 경우 에러 메세지
                        });
                      } else {
                        setState(() {
                          error = null; // 내용이 있는 경우 에러 메세지 숨기기
                        });
                        BucketService bucketService = context.read<BucketService>();
                        bucketService.createBucket(job);
                        Navigator.pop(context); // 화면을 종료합니다.
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }

     

     

    [ bucketservice provider]

    import 'package:bucket_provider/main.dart';
    import 'package:flutter/material.dart';
    
    class BucketService extends ChangeNotifier {
      List<Bucket> bucketList = [
        Bucket('잠자기', false),
      ];
    
      void createBucket(String job) {
        bucketList.add(Bucket(job, false));
        notifyListeners(); //ChangeNotifier 상속을 받아서 notifyListeners() 사용가능, setstate()처럼 화면 갱신이 있다는 것을 알려줌
      }
    
      /// bucket 수정
      void updateBucket(Bucket bucket, int index) {
        bucketList[index] = bucket;
        notifyListeners();
      }
    
      void deletBucket(int index) {
        bucketList.removeAt(index);
        notifyListeners();
      }
    }
    반응형
Designed by Tistory.