-
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(); } }
반응형'프로그래밍 공부 메모 > flutter' 카테고리의 다른 글
statelees / stateful 일때 다음화면에 데이터 전달하기 (0) 2022.06.16 firstwhere(),where(), toList(), toSet(), any(), map() (0) 2022.06.14 다이얼로그 창 (0) 2022.06.09 ListView / ListTitle (0) 2022.06.08 shared_preferences 패키지 (0) 2022.06.08