Flutter data transfer

In the process of data transfer during application development, flutter provides InheritedWidget and various providers , each with its own differences. From the usage habits above, the following two types are mainly introduced:

  • InheritedWidget
  • provider   (ChangeNotifier)

 InheritedWidget:

Provide a top- down data provision (and child nodes need Widget package); and one-way . Remember that the data can only be refreshed from top to bottom ; it cannot be refreshed when the child node changes data! It is often used for static data storage; constant storage that will not change; or child nodes are only used as static display data , and parent nodes provide metadata. Sub-node display data does not participate in dynamic update interaction

 

The effect is as follows:

Script structure:

 inherited_datum.dart

import 'package:flutter/cupertino.dart';

class InheritedDatum extends InheritedWidget {
  final int count;
  const InheritedDatum({Key? key, required child, required this.count})
      : super(key: key, child: child);

  static InheritedDatum? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<InheritedDatum>();
  }

  ///**子组件不能 通过调用该方法 实现子组件刷新
  updateCount(int count) {
    count = count;
  }

  @override
  bool updateShouldNotify(covariant InheritedDatum oldWidget) {
    // TODO: implement updateShouldNotify
    return oldWidget.count != count;
  }
}

widget_child0.dart

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

import 'inherited_datum.dart';

class WidgetChild0 extends StatelessWidget {
  const WidgetChild0({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      height: 40,
      width: 80,
      child: Center(
        child: Text(
          '${InheritedDatum.of(context)?.count}',
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}

widget_child1.dart

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

import 'inherited_datum.dart';

class WidgetChild1 extends StatelessWidget {
  const WidgetChild1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      height: 40,
      width: 80,
      child: Center(
        child: Text(
          '${InheritedDatum.of(context)?.count}',
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}

Entry: main.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      // Here we take the value from the MyHomePage object that was created by
      // the App.build method, and use it to set our appbar title.
      title: Text(widget.title),
    ),
    body: Center(
      child: InheritedDatum(
        count: _counter,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          // children: const [],
          children: const [WidgetChild0(), WidgetChild1()],
        ),
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: _incrementCounter,
      tooltip: 'Increment',
      child: const Icon(Icons.add),
    ), // This trailing comma makes auto-formatting nicer for build methods.
  );
}

InheritedWidget uses attention to details:

1. It must be a subcomponent : parallel ones will not work:

2. The subcomponent obtains the data in InheritedWidget through :

InheritedDatum.of(context)?.count

3. Subcomponents cannot refresh subcomponents only by calling the convenience in InheritedWidget

Summary :

        Applicable scenarios of InheritedWidget : child components share the data in the parent component; but do not have the ability to modify and update the data in the parent component! The ChangeNotifier introduced below has the ability to update data up and down

Provider     data transfer

Provider is a wrapper based on InheritedWidget; in order to share data in Provider, we first need to define a data model for it. In order to be able to subscribe to the state of data, this data model is usually inherited from provider: ^ 6.0.5ChangeNotifier,达到更新的目的; 使用前先导入

dependencies:
  flutter:
    sdk: flutter

  provider: ^6.0.5

Previous summary : https://johns.blog.csdn.net/article/details/122139508

The following components need to be used in the parent node to complete the update of the child components : according to the complexity of the update logic. Select the appropriate model according to actual needs

  • ChangeNotifierProvider
  • ProxyProvider
  • MultiProvider
  • Consumer

The effect is as follows:

Both parent and child components can update data

 

Script structure:

counter.dart

import 'package:flutter/cupertino.dart';

class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;
  void increment() {
    _count++;
    notifyListeners();
  }

  void set(int count) {
    _count = count;
    notifyListeners();
  }
}

 widget_child0.dart

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

class WidgetChild0 extends StatelessWidget {
  const WidgetChild0({Key? key}) : super(key: key);

  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      height: 40,
      width: 80,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          context.read<Counter>().set(0);
          print('WidgetChild0');
        },
        child: Center(
          child: Text(
            '${context.watch<Counter>().count}',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );
  }
}

widget_child1.dart

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

class WidgetChild1 extends StatelessWidget {
  const WidgetChild1({Key? key}) : super(key: key);

  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      height: 40,
      width: 80,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          context.read<Counter>().set(1);
          print('WidgetChild1');
        },
        child: Center(
          child: Text(
            '${context.watch<Counter>().count}',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );
  }
}

main.dart

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChangeNotifierProvider(
        create: (_) => Counter(),
        child: const MyHomePage(title: 'Flutter Demo Home Page'),
      ),
      //home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          // children: const [],
          children: const [WidgetChild0(), WidgetChild1()],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.read<Counter>().increment();
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

Provide pay attention to details:

The shared data also needs to be placed in the parent node; the data can be modified and updated in the shared parent node; to achieve two-way dynamic data: call

notifyListeners

Among them, MultiProvider and Consumer are suitable for multiple sets of ChangeNotifier; to achieve decoupling operations; the basic usage is the same as ChangeNotifierProvider; for details, please refer to: https://johns.blog.csdn.net/article/details/122139508 https://johns.blog. csdn.net/article/details/122139508

Guess you like

Origin blog.csdn.net/nicepainkiller/article/details/129235765