state(상태)를 수정할수 있는 방법을 제공하는 provider 입니다. StateNotifierProvider의 심플버전인데 state가 아래의 경우에 사용하는걸 권장합니다.
권장하지 않는 경우는 아래와 같습니다. 이런 경우에는 StateNotifierProvider를 권장합니다.
아래는 dropdown 을 이용해서 filter type 을 바꾸는 예제 입니다.
class Product {
Product({required this.name, required this.price});
final String name;
final double price;
}
final _products = [
Product(name: 'iPhone', price: 999),
Product(name: 'cookie', price: 2),
Product(name: 'ps5', price: 500),
];
final productsProvider = Provider<List<Product>>((ref) {
return _products;
});
Widget build(BuildContext context, WidgetRef ref) {
final products = ref.watch(productsProvider);
return Scaffold(
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ListTile(
title: Text(product.name),
subtitle: Text('${product.price} \$'),
);
},
),
);
}
// An enum representing the filter type
enum ProductSortType {
name,
price,
}
Widget build(BuildContext context, WidgetRef ref) {
final products = ref.watch(productsProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Products'),
actions: [
DropdownButton<ProductSortType>(
value: ProductSortType.price,
onChanged: (value) {},
items: const [
DropdownMenuItem(
value: ProductSortType.name,
child: Icon(Icons.sort_by_alpha),
),
DropdownMenuItem(
value: ProductSortType.price,
child: Icon(Icons.sort),
),
],
),
],
),
body: ListView.builder(
// ...
),
);
}
final productSortTypeProvider = StateProvider<ProductSortType>(
// We return the default sort type, here name.
(ref) => ProductSortType.name,
);
DropdownButton<ProductSortType>(
// When the sort type changes, this will rebuild the dropdown
// to update the icon shown.
value: ref.watch(productSortTypeProvider),
// When the user interacts with the dropdown, we update the provider state.
onChanged: (value) =>
ref.read(productSortTypeProvider.notifier).state = value!,
items: [
// ...
],
),
final productsProvider = Provider<List<Product>>((ref) {
final sortType = ref.watch(productSortTypeProvider);
switch (sortType) {
case ProductSortType.name:
return _products.sorted((a, b) => a.name.compareTo(b.name));
case ProductSortType.price:
return _products.sorted((a, b) => a.price.compareTo(b.price));
}
});