Flutter狀態管理Provider,簡單上手

學習Flutter一段時間了,偶然看到你們都說狀態管理,多數人都是用redux,對於一個Android開發人員來講以前根本沒接觸過,因而開始瞭解redux,以後又瞭解閒魚推出的fish_redux,而後又看到Vadaski發表的一系列關於Flutter狀態管理的文章,包括Scoped Model, Redux, BLoC,RxDart,provide(想了解的能夠移步),看的是眼花繚亂。對於Redux,能看懂是怎麼寫的,但真要到應用的層面,感受仍是有些吃力,更不知道怎樣維護好它,一時間也不知道用什麼什麼適合本身。後來又接觸到google推薦的Provider,因而學習了下。接下來就用Provider來實現一個計數的例子。git

第一步,添加Provider依賴

provider: ^2.0.1+1
複製代碼

pub地址:pub.dev/packages/pr…github

第二步,建立Model

import 'package:provider/provider.dart';
class Counter with ChangeNotifier {//1
  int _count;
  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();//2
  }
  get count => _count;//3
}
複製代碼

簡單的一個Counter對象,裏面只有一個字段_countredux

  1. 這裏須要混入ChangeNotifier
  2. 寫一個增長的方法,而後須要調用notifyListeners();這個方法是通知用到Counter對象的widget刷新用的。
  3. get方法

第三步,使用ChangeNotifierProvider

一般main()方法是這麼寫bash

main() {
  runApp(MyApp());
}
複製代碼

咱們要監聽改變就要在MyApp()外面套一層,這個是全局的,因而以下app

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

main() {
  runApp(ChangeNotifierProvider<Counter>.value(//1
    notifier: Counter(1),//2
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

複製代碼
  1. ChangeNotifierProvider調用value()方法,裏面傳出notifierchild
  2. notifier設置了默認的Counter(1)

固然Provider不止提供了ChangeNotifierProvider,還有Provider,ListenableProvider,ValueListenableProvider,StreamProvider, 具體能夠看wiki. 若是想管理多個對象能夠用MultiProvider,以下less

MultiProvider(
  providers: [
    Provider<User>.value(value: user),
    Provider<Goods>.value(value: goods),
    .....
  ],
  child: someWidget,
)
複製代碼

第四步,使用Provider獲取Counter的值

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一頁"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
複製代碼
  1. Provider.of<Counter>(context).count獲取_count的值,Provider.of<T>(context)至關於Provider去查找它管理的Counter(1)
  2. Provider.of<Counter>(context).add();調用Counter()中的add()方法

一樣第二個頁面也這樣寫,以下ide

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("SecondPage"),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
複製代碼

這樣,當每一個頁面都點擊+號按鈕時,_count便會+1,同時通知並更新到使用它的地方。post

完整代碼,copy後可直接運行學習

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

main() {
  runApp(ChangeNotifierProvider<Counter>.value(
    notifier: Counter(1),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一頁"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(Provider.of<String>(context)),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class Counter with ChangeNotifier {

  int _count;

  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();
  }

  get count => _count;
}
複製代碼

總結

看了那麼多狀態管理的,我的感受Provider仍是屬於簡單易用的,而且是google推薦的。但感受還須要成長,讓你們承認。我這裏只是一個簡單的使用,有一些地方也沒講太清楚還請你們見諒,同時也但願和各位學習Flutter的同窗互相交流進步。ui

相關文章
相關標籤/搜索