簡體   English   中英

將數據從小部件發送到 flutter 中的另一個小部件

[英]send data from widget to another widget in flutter

我想將數據從小部件發送到另一個小部件,在我的示例中,我想將一些過濾器數據從 FilterScreen.dart 發送到 ShopScreen.dart 它工作正常,但我不知道我在做什么是正確的?

在過濾器 model 文件中:

class FilterData with ChangeNotifier {
  bool isFreeShipping;
  bool isSomeThingElse;

  FilterData({this.isFreeShipping = false, this.isSomeThingElse = false});

  void setFreeShippingValue(bool newval) {
    isFreeShipping = newval;
    notifyListeners();
  }

  void setSomeThingElseValue(bool newval) {
    isSomeThingElse = newval;
    notifyListeners();
  }
}

在 main.dart 中:

return ChangeNotifierProvider(
      create: (context) => FilterData(),
      child: MaterialApp(
       .........
    )
);

在標簽屏幕中:

class TabsScreen extends StatefulWidget {
  @override
  _TabsScreenState createState() => _TabsScreenState();
}

class _TabsScreenState extends State<TabsScreen> {
  List<Map<String, Object>> _pages;
  int _selectedPageIndex = 0;

  @override
  void initState() {
    _pages = [
      {
        'page': ShopScreen(),
        'title': 'shop',
      },
      {
        'page': FilterScreen(),
        'title': 'filter',
      },
    ];
    super.initState();
  }

  void _selectPage(int index) {
    setState(() {
      _selectedPageIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_pages[_selectedPageIndex]['title']),
      ),
      drawer: DrawerApp(),
      body: _pages[_selectedPageIndex]['page'],
      bottomNavigationBar: BottomNavigationBar(
        onTap: _selectPage,
        backgroundColor: Theme.of(context).primaryColor,
        unselectedItemColor: Colors.white,
        selectedItemColor: Theme.of(context).accentColor,
        currentIndex: _selectedPageIndex,
        // type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(
            backgroundColor: Theme.of(context).primaryColor,
            icon: Icon(Icons.shop),
            title: Text('Shop'),
          ),
          BottomNavigationBarItem(
            backgroundColor: Theme.of(context).primaryColor,
            icon: Icon(Icons.search),
            title: Text('Filter'),
          ),
        ],
      ),
    );
  }
}

在 FilterScreen.dart 中:

class FilterScreen extends StatefulWidget {
  @override
  _FilterScreenState createState() => _FilterScreenState();
}

class _FilterScreenState extends State<FilterScreen> {
  @override
  Widget build(BuildContext context) {
    final data = Provider.of<FilterData>(context);

    return Container(
      child: Center(
        child: Expanded(
          child: ListView(
            children: <Widget>[
              SwitchListTile(
                  title: Text('Free Shipping'),
                  value: data.isFreeShipping,
                  subtitle: Text('get free shipping products'),
                  onChanged: (newValue) {
                    data.setFreeShippingValue(newValue);
                  }),
              SwitchListTile(
                  title: Text('Some thing else'),
                  value: data.isSomeThingElse,
                  subtitle: Text('get filtred products'),
                  onChanged: (newValue) {
                    data.setSomeThingElseValue(newValue);
                  }),
            ],
          ),
        ),
      ),
    );
  }
}

在 ShopScreen.dart 中:

class ShopScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final data = Provider.of<FilterData>(context);

    return Container(
      child: Center(
        child: Text(
            data.isFreeShipping ? 'get favorite Products' : 'get all products'),
      ),
    );
  }
}

在此處輸入圖像描述

您的問題確實是大多數開發人員的痛苦,就像我不知道它是如何工作的!

所以,如果你無法理解。 有兩個原因:

  • 您只是盲目地遵循教程或文檔,因為時間限制
  • 你不明白Flutter Provider State Management works的。 因此,為此,請閱讀以下內容:

所以,現在讓我們跳到代碼。 你的代碼是如何工作的?

有很多事情要為此負責:

1. Provider Wrap:如果你仔細查看main.dart代碼,你已經做到了

return ChangeNotifierProvider(
      create: (context) => FilterData(), // here you define the ChangeNotifier class
      child: MaterialApp(
       .........
    )
);

現在查看上面的代碼,您會看到,每當您使用ChangeNotifierProvider()包裝應用程序時,只要您在其中提供的 class 中存在 state 更改(在本例中為FilterData() ),它總是會重新構建。 發生的任何更改都將反映在整個應用程序中,因為ChangeNotifierProvider()正在繼續重建直系孩子的 state,在這種情況下,您的MaterialApp()已被包裝。

2.來自 ChangeNotifier class 的 NotifyChanges:如果您查看FilterData ,它是負責重建應用程序的那個,它由ChangeNotifierProvider()包裝。

讓我們看看如何:

  void setFreeShippingValue(bool newval) {
    isFreeShipping = newval;
    notifyListeners();
  }

  void setSomeThingElseValue(bool newval) {
    isSomeThingElse = newval;
    notifyListeners();
  }

如果您仔細查看我在上述代碼中僅從您的FilterData class 中提到的方法,它們具有notifyListeners() 這些是負責的,每當您調用兩個方法時,它都會通知ChangeNotifierListener重建小部件,因此您每次都會看到更新的數據,您可以使用這兩種方法中的任何一種

3.使用FilterScreen中FilterData中的NotifyListeneres方法:所以,再次仔細觀察我們在第2點中提到的事情,我們看到,應該調用方法方法來在App中進行更改,即立即ChangeNotifierProvider()的子級

                 SwitchListTile(
                  title: Text('Free Shipping'),
                  value: data.isFreeShipping,
                  subtitle: Text('get free shipping products'),
                  onChanged: (newValue) {
                    data.setFreeShippingValue(newValue);
                  }),
              SwitchListTile(
                  title: Text('Some thing else'),
                  value: data.isSomeThingElse,
                  subtitle: Text('get filtred products'),
                  onChanged: (newValue) {
                    data.setSomeThingElseValue(newValue);
                  }),

因此,當您調用onChanged中的任何方法時,它會立即通知 Provider 值已更改,並且應用程序會重新構建,當您切換到另一個選項卡時,您會看到更新的結果,就像魔術一樣。

最重要的:您的final data = Provider.of<FilterData>(context); , 是 Provider class 的一個實例,它觸發了幫助通知ChangeNotifierProvider()在應用程序中進行更改的方法

所以映射是這樣的:

                                                          Listens to the change
FilterData {setFreeShippingValue, setSomeThingElseValue} <----------------------> ChangeNotifierProvider() REBUILDS MATERIALAPP()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM