flutter狀態管理Provider的使用學習

本文主要介紹flutter中狀態管理組件provider,provider: ^6.0.3主要是用於我們系統InheritedWidge的封裝,用於數據的傳遞和管理。

1. provider的使用

網上也有很多關於provider說明,也可以看下官方的provider的 README。這裡我記錄一下我自己學習。
我們對於簡單的數據共享可以設置參數,之後子頁面進行數據方法回調,從而完成數據間的通信。但是比較麻煩,下面我們看下我們使用provider如何達到這個效果。

我們2個頁面使用同一個數據,在第二個頁面使用點擊增加方法。之後返回在第一個頁面也顯示出增加後的數據count達到同步的效果。

點擊增加

看下代碼實現首先是使用StatelessWidget來顯示頁面,簡單的頁面跳轉就不展示瞭。我們定義一個model用來存儲我們的count,我麼混入通過混入 ChangeNotifier 管理監聽者(通知模式)。我們寫讀數據,並且當數據發生改變的時候,使用通知更新數據。

class CountModel with ChangeNotifier {
  int _count = 0;
  // 讀方法
  int get counter => _count;
  // 寫方法
  void increment() {
    _count++;
    notifyListeners(); // 通知監聽者刷新
  }
}

我們2個頁面都要使用這個數據,我們要把這個數據放在這2個子頁面的父節點上。通過 Provider 組件封裝數據資源,value就是需要共享的數據資源

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    // 通過 Provider 組件封裝數據資源
    return ChangeNotifierProvider.value(
        value: CountModel(), // 需要共享的數據資源
        child: MaterialApp(
          home: FirstPage(),
        ));
  }
}

我們在頁面使用的地方進行取數據

final _counter = Provider.of<CountModel>(context);

上下文就包含瞭我們父節點中設置的value 即CountModel()。

// 第一個頁面
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 取出數據
    final _counter = Provider.of&lt;CountModel&gt;(context);
    return Scaffold(
        appBar: AppBar(
          title: const Text('第一個頁面'),
        ),
        body: Center(
          child: Text('第一個頁面count:${_counter.counter}'),
        ),
        // 跳轉到 SecondPage
        floatingActionButton: FloatingActionButton(
            child: const Icon(Icons.next_plan),
            onPressed: () =&gt; Navigator.of(context)
                .push(MaterialPageRoute(builder: (context) =&gt; SecondPage()))));
  }
}
// 第二個頁面
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 取出數據
    final _counter = Provider.of&lt;CountModel&gt;(context);
    return Scaffold(
        appBar: AppBar(
          title: const Text('第二個頁面'),
        ),
        // 展示資源中的數據
        body: Center(
          child: Text('第二個頁面count:${_counter.counter}'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _counter.increment,
          child: const Icon(Icons.add),
        ),
    );
  }
}

通過provider很簡單的達到瞭我們的數據共享,同時通過通知讓我們的頁面進行瞭刷新。

2. 控制Widget的刷新顆粒度

我們上面的頁面中涉及的Widget變化也就是一個文字的展示,沒有必要整個頁面都刷新,這樣可以提高我們的性能。

我們把我們Icon換成自定義的,可以發現當我們點擊的時候就會一直重新build,實際我們不需要他們變化,那麼我們隻要我們那個Widget使用瞭數據,我們刷新該Widget即可。我們就要使用Consumer

final Widget Function(
  BuildContext context,
  T value,
  Widget? child,
) builder;

定義child為我們包裹的widget,T為我們model的類型。

body: Center(
  child: Consumer<CountModel>(
    builder: (context,CountModel counter,_) => Text('第二個頁面count:${counter.counter}'),
  ),
),

這裡我們的child為空直接每次刷新Consumer的Widget。那麼我們的button怎麼刷新呢

floatingActionButton: Consumer<CountModel>(
  builder: (context, CountModel counter, child) => FloatingActionButton(
    onPressed: counter.increment,
    child: child,
  ),
  child: MyIcon(),
)

這裡我們使用child屬性,把我們的builder隔離開,這樣我們就可以是我們的數據和視圖做到隔離效果。

3. 小結

對於數據共享和數據傳遞provider組件確實提供瞭我們快捷的方式,我們在使用的過程中要註意provider組件位於父節點位置,這樣子節點才能共享數據狀態,其次我們盡可能的減少我們刷新的顆粒度,最好在使用數據的地方進行刷新組件。

以上就是flutter狀態管理Provider的使用學習的詳細內容,更多關於flutter狀態管理Provider的資料請關註WalkonNet其它相關文章!

推薦閱讀: