iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Mobile Development

Flutter Didilong系列 第 19

D-19 Provider | Flutter筆記

  • 分享至 

  • xImage
  •  

Provider聽起來就很帥吧?

在Flutter裡通通都是widget
在官方範例中也常見到他畫出APP的Widget tree
https://ithelp.ithome.com.tw/upload/images/20220924/20129416REX2C9vmut.jpg

在使用過statefulWidget後
會發現有些數值只存在於子widget的狀態中

使用上方widget tree圖片舉例
商品目錄MyCatalog , 將商品加入購物車
購物車MyCart,就得要顯示剛剛那件物品

經過這點會發現MyCatalog MyCart各自的statefulWidget
怎麼能共用資料讓購物車在兩個畫面都能操作


此處會使用
Counter:點按鈕增加畫面上數字的demo

我們開始看範例

Provider範例

ChangeNotifier: 繼承後代表可以去監聽Counter value數值的變化
increment : 使value增加 notifyListeners()
讓有使用Consumer的widget更新

class Counter with ChangeNotifier {
  int value = 0;

  void increment() {
    value += 1;
    notifyListeners();
  }
}
  • p1 : ChangeNotifierProvider 表示你的Counter能夠在ShopView上使用

main.dart

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      initialRoute: '/',
      routes: {
        '/': (context) => const MainView(),
        BASIC: (context) => const BasicView(),
        IMAGEPICKER: (context) => const ImagePickerPage(),
        CALLBACK: (context) => const CallBackView(),
        //p1
        SHOP: (context) => ChangeNotifierProvider(
              create: (context) => Counter(),
              child: const ShopView(),
            ),
      },
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
    );
  }
  • p2 Consumer 加在 顯示Counter value的widget上
    使他能得知Counter value更新(數值增加)
  • p3 context.read<Counter>() 讀取Counter
    使用increment() 使Counter value增加
class ShopView extends StatefulWidget {
  const ShopView({Key? key}) : super(key: key);
  @override
  State<ShopView> createState() => _ShopViewState();
}

class _ShopViewState extends State<ShopView> {
  @override
  Widget build(BuildContext context) {
    var snackBar = SnackBar(
      content: const Text(
        '您正離開商品頁唷!',
      ),
      action: SnackBarAction(
        label: '知道了',
        onPressed: () => showDialog(
          barrierDismissible: true,
          context: context,
          builder: (context) => Container(
            alignment: Alignment.center,
            child: const DefaultTextStyle(
              style: TextStyle(fontSize: 30),
              child: Text('知道就知道'),
            ),
          ),
        ),
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(MyApp.SHOP.replaceAll('/', '')),
      ),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(
                color: Colors.black45,
              ),
              child: Text('Drawer Header'),
            ),
            ListTile(
              title: const Text('個人頁面'),
              onTap: (() => Navigator.pop(context)),
            ),
            ListTile(
              title: const Text('離開'),
              onTap: () => {
                Navigator.popAndPushNamed(context, '/'),
                ScaffoldMessenger.of(context).showSnackBar(snackBar),
              },
            ),
          ],
        ),
      ),
      body: Container(
        color: Colors.black38,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                //p2
                Consumer<Counter>(
                  builder: ((context, couter, child) => Text('Count is: ${couter.value}')),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    //p3
                    var counter = context.read<Counter>();
                    counter.increment();
                  },
                  child: const Icon(Icons.add),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}


成果展示


上一篇
D-18 SnackBar | Flutter筆記
下一篇
D-20 Provider 購物車實作(上) | Flutter筆記
系列文
Flutter Didilong30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言