[譯]在底部導航欄裏使用 Provider

在這篇文章裏,我將向你展現在 BottomNavigationBar 裏如何使用 Flutter 的 Provider。git

什麼是 Provider?

Provider 是 Flutter 團隊推薦的新的狀態管理方法。github

雖然 setState 能夠用於大多數場景,可是建議你不要用。尤爲是你用了 FlutterBuilder,而後在用 setState,就會使你的代碼很混亂,會形成不少問題。 bash

接下來讓咱們看如何在 BottomNavigationBar 裏使用 Provider。less

Step 1: 在 pubspec.yaml 裏添加 Provider 的依賴

provider: ^3.0.0+1
複製代碼

Step2: 建立一個 Provider 的類

class BottomNavigationBarProvider with ChangeNotifier {
  int _currentIndex = 0;

  get currentIndex => _currentIndex;

  set currentIndex(int index) {
    _currentIndex = index;
    notifyListeners();
  }
}
複製代碼

在這個 Provider 裏,我存儲了 BottomNavigationBar 的當前表示展現第幾個頁面的索引的值,當設置新的索引的值以後,BottomNavigationBar 將會受到最新的值,而且刷新 tab。ide

Step 3:使用 BottomNavigationBarProvider 來包 Widget

home: ChangeNotifierProvider<BottomNavigationBarProvider>(
  child: BottomNavigationBarExample(),
  builder: (BuildContext context) => BottomNavigationBarProvider(),
),
複製代碼

由於使用 ChangeNotifierProvider 包了 Widget,因此當 ChangeNotifierProvider 裏的 _currentIndex 值發生變化的時候,Widget 就會收到通知。ui

Step 4:實現 BottomNavigationBar 的 tabs

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Container(
        alignment: Alignment.center,
        height: 300,
        width: 300,
        child: Text(
          "Home",
          style: TextStyle(color: Colors.white, fontSize: 30),
        ),
        color: Colors.amber,
      )),
    );
  }
}
複製代碼
class Profile extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          alignment: Alignment.center,
          height: 300,
          width: 300,
          child: Text(
            "Profile",
            style: TextStyle(color: Colors.white, fontSize: 30),
          ),
          color: Colors.blue,
        ),
      ),
    );
  }
}
複製代碼
class Setting extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Container(
        alignment: Alignment.center,
        height: 300,
        width: 300,
        child: Text(
          "Settings",
          style: TextStyle(color: Colors.white, fontSize: 30),
        ),
        color: Colors.cyan,
      )),
    );
  }
}
複製代碼

這裏建立裏 BottomNavigationBar 裏要使用的 3 個 tabs。spa

Step 5:使用 Provider 建立 BottomNavigationBarExample

class BottomNavigationBarExample extends StatefulWidget {
  @override
  _BottomNavigationBarExampleState createState() =>
      _BottomNavigationBarExampleState();
}

class _BottomNavigationBarExampleState
    extends State<BottomNavigationBarExample> {
  var currentTab = [
    Home(),
    Profile(),
    Setting(),
  ];

  @override
  Widget build(BuildContext context) {
    var provider = Provider.of<BottomNavigationBarProvider>(context);
    return Scaffold(
      body: currentTab[provider.currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: provider.currentIndex,
        onTap: (index) {
          provider.currentIndex = index;
        },
        items: [
          BottomNavigationBarItem(
            icon: new Icon(Icons.home),
            title: new Text('Home'),
          ),
          BottomNavigationBarItem(
            icon: new Icon(Icons.person),
            title: new Text('Profile'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            title: Text('Settings'),
          )
        ],
      ),
    );
  }
}
複製代碼

這裏使用 Provider 的代碼爲:code

@override
  Widget build(BuildContext context) {
    var provider = Provider.of<BottomNavigationBarProvider>(context);
    return Scaffold(
      ...
      bottomNavigationBar: BottomNavigationBar(
        ...
        onTap: (index) {
          provider.currentIndex = index;
        },
        ...
      )
    )
  }
複製代碼

至此,建立了一個使用底部導航欄切換頁面的應用,並且底部導航欄的切換使用到的當前頁面的索引的值由 Provider 更新。cdn

Github 代碼

這裏是本篇文章涉及到的代碼:github.com/flutter-dev…blog

持續化 BottomNavigationBar

Provide 不須要使用 setState 就能夠變化顯示的 tabs,可是若是你想持久化當前頁面的狀態,例如,下次打開 APP 時記住上次打開的是哪一個頁面,可使用 PageStorageBucket,能夠看我另外的一個實例,地址是: github.com/tensor-prog…

原文連接

medium.com/flutterdevs…

相關文章
相關標籤/搜索