프로그래밍 공부 메모/flutter
provider 다루기
jjs815
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();
}
}
반응형