【问题标题】: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

【问题讨论】:

    标签: flutter dart flutter-provider state-management flutter-widget


    【解决方案1】:

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

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

    • 你只是盲目地按照教程或文档,因为时间限制
    • 你不明白Flutter Provider State Management works。因此,为此,请阅读以下内容:

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

    有多种原因导致此问题:

    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()
    

    【讨论】:

      猜你喜欢
      • 2020-08-08
      • 1970-01-01
      • 2020-08-20
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 2021-01-01
      相关资源
      最近更新 更多