在颤动中将数据从小部件发送到另一个小部件

Posted

技术标签:

【中文标题】在颤动中将数据从小部件发送到另一个小部件【英文标题】:send data from widget to another widget in flutter 【发布时间】:2020-11-15 11:23:32 【问题描述】:

我想将数据从小部件发送到另一个小部件,在我的示例中,我想将一些过滤器数据从 FilterScreen.dart 发送到 ShopScreen.dart 它工作正常,但我不知道我在做什么是正确的?

在过滤器模型文件中:

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'),
      ),
    );
  

enter image description here

【问题讨论】:

【参考方案1】:

您的问题确实让大多数开发人员感到痛苦,就像 我不知道它是如何工作的!

所以,如果你无法理解。有两个原因:

你只是盲目地按照教程或文档,因为时间限制 你不明白Flutter Provider State Management works。因此,为此,请阅读以下内容: List of state managements in flutter Flutter provider package,当然你已经在你的项目中使用了它。但是请阅读他的使用方式。

那么,现在让我们跳到代码。 您的代码是如何工作的?

有多种原因导致此问题:

1. Provider Wrap:如果您仔细查看main.dart 代码,您已经做到了

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

现在查看上面的代码,您会看到,每当您使用 ChangeNotifierProvider() 包装应用程序时,它总是只要您在其中提供的类中发生状态更改就会重新构建,在这种情况下FilterData()。发生的任何更改都将反映在整个应用程序中,因为 ChangeNotifierProvider() 正在不断重建直接子项的状态,在这种情况下,您的 MaterialApp() 已被包装。

2。 ChangeNotifier 类中的 NotifyChanges: 如果您查看您的 FilterData,它负责重建应用程序,由 ChangeNotifierProvider() 包装。

让我们看看如何:

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

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

如果您仔细查看我在上面的代码中仅从您的FilterData 类中提到的方法,它们有notifyListeners()。这些是负责的,每当您调用两个方法时,它都会通知ChangeNotifierListener 重建小部件,因此您每次都会看到更新的数据,您可以使用这两种方法中的任何一种

3.使用 FilterScreen 中 FilterData 中的 NotifyListeneres 方法: 所以,如果我们再次仔细查看我们在 第 2 点 中提到的内容,我们会看到,方法方法应该被调用到在 ChangeNotifierProvider() 的直接子 App 中进行更改

                 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&lt;FilterData&gt;(context);,是Provider 类的一个实例,它触发方法来帮助通知ChangeNotifierProvider() 在应用程序中进行更改

所以映射是这样的:

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

【讨论】:

以上是关于在颤动中将数据从小部件发送到另一个小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何将 onPressed 值发送到另一个小部件 Flutter

如何在颤动中将 ListTile 连接到音频小部件

如何在颤动中将Json数据传递到多屏

qt 小部件在添加到另一个小部件时重叠

如何在颤动中加载主小部件之前显示加载小部件?

如何根据列表中的数据在颤动中渲染多个小部件?