Flutter狀態管理-04-Provider

天色將變發表於2021-03-02

Provider 是Google推薦的狀態管理工具之一 pub官網:pub.dev/packages/pr…

新增依賴
dependencies:
  provider: ^4.3.2+1
複製程式碼

然後 :flutter pub get

使用時幾個重要的點
  • 定義一個類,讓其with ChangeNotifier,在該類內是業務資料,和對業務資料進行的操作。
  • MutiProvider 要成為根節點,也就是放到runApp內。並且要把自定義的類放到Multiprovider內。
  • 在widget內運算元據時,context.read().xxx(); xxx代表業務方法
  • 在widget內讀取資料時,context.watch().data; data代表業務資料

這樣,就把業務類,資料讀取和資料操作完全分離開了。

示例

還是以加數字為例

  • 定義業務邏輯類Counter
class Counter with ChangeNotifier,DiagnosticableTreeMixin{
  int _count = 0;
  int get count => _count;
  increment(){
    _count++;
    notifyListeners();
  }
  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    // TODO: implement debugFillProperties
    super.debugFillProperties(properties);
    properties.add(IntProperty("count",count));
  }
}
複製程式碼

_count:代表業務資料 int get count => _count: 代表對業務資料的訪問 increment(): 代表對業務資料的操作

  • 將Provider整體註冊到根節點,並將自定義的業務資料類Counter放到根節點下
void main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_)=>Counter(),)
    ],
    child: MyApp(),
  ));
}
複製程式碼
  • 在widget中讀取業務資料,context.watch().count.toString();
class CountWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var str = context.watch<Counter>().count.toString();
    return Text(
      str
    );
  }
複製程式碼
  • 在widget中操作業務資料, context.read().increment();
 floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: (){
          context.read<Counter>().increment();
        },
      )
複製程式碼
完整程式碼
  • main.dart
void main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_)=>Counter(),)
    ],
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
//      home: MyHomePage(title: 'Flutter Demo Home Page'),
      home: ProviderTest(),
    );
  }
}
複製程式碼
  • provider_test.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderTest extends StatefulWidget {
  @override
  _ProviderTestState createState() => _ProviderTestState();
}

class _ProviderTestState extends State<ProviderTest> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Provider"),
      ),
      body: Center(
        child: CountWidget(),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: (){
          context.read<Counter>().increment();
        },
      )
    );
  }
}


class Counter with ChangeNotifier,DiagnosticableTreeMixin{
  int _count = 0;
  int get count => _count;
  increment(){
    _count++;
    notifyListeners();
  }
  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    // TODO: implement debugFillProperties
    super.debugFillProperties(properties);
    properties.add(IntProperty("count",count));
  }
}

class CountWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var str = context.watch<Counter>().count.toString();
    return Text(
      str
    );
  }
}

複製程式碼

相關文章