This is the 13th day of my participation in the August More text Challenge. For details, see: August More Text Challenge
preface
We talked about two ways that providers implement state management:
- Putting the Provider at the top level allows all application subpages to access the status data: Flutter Introduction and Practice (47) : Use the Provider to modify the same code as π©, reducing the code volume by 2/3! ;
- Nested Component Management using MultiProvider: Introduction and Practice with Flutter (49) : Can Providers do nested state management?
That begs the question, can two unrelated pages share status? For example, our dynamic add and edit pages belong to the same hierarchy. If we do not consider using their parent component to complete state sharing, then the two pages are parallel and unrelated, but many of their methods and data can be shared. In this case, the Provider provides a way to share the state by having two pages share the same state object.
MyChangeNotifier variable;
ChangeNotifierProvider.value(
value: variable,
child: ...
)
Copy the code
Using ChangeNofitierProvider. Value method can make use of an existing object provides state management, and the existing object can be Shared for other components.
Transformation state management class
Many methods and data for adding and editing pages can be shared, such as:
handleTextFieldChanged
: Update the corresponding form content when the text input value changes;handleClear
: Clear the content of the corresponding form when clicking the clear button;handleImagePicked
: Picture selection control updates the selected picture;_imageFile
: The selected image file._formData
The configuration of the: form is common, but the add page has no initial value, and the edit page needs to use the existing dynamic population.
To ensure that the add and edit pages share a state object, we need to provide a shared object for the class, which naturally requires the use of static singletons. DynamicShareModel = DynamicShareModel = DynamicShareModel = DynamicShareModel
class DynamicShareModel with ChangeNotifier {
DynamicShareModel._privateConstructor();
static final DynamicShareModel sharedDynamicModel =
DynamicShareModel._privateConstructor();
/ /...
}
Copy the code
At the same time, for adding and editing pages, the form data and cached dynamic objects should be cleared before entering the rendering interface; otherwise, the old data rendering interface will be used for adding and editing pages (for example, after editing, entering the add page will render the newly edited form data). Therefore, you need to provide a way to clear cached state data:
clearState() {
_currentDynamic = null;
_imageFile = null;
_formData.forEach((key, form) {
form['value'] = ' ';
(form['controller'] asTextEditingController)? .text =' ';
});
}
Copy the code
Then there is the difference method to improve the addition and editing:
getDynamic
Get the current dynamic object using the dynamic ID and notify the edit interface to render the form after success — dynamically fill the form according to the existing one.handleAdd
: Adds dynamic network submission and processing methods.handleEdit
: Edit dynamic network submission and processing methods._validateForm
: : Validates the form. If you want to add a page, you need to check whether an image is selected.
Source code is longer, do not paste, has been uploaded to: state management code.
Page code transformation
At this point we need to clear the state cache after the add page is entered, so we need to be managed by the life cycle. We need to make the add page StatefulWidget and then clear the state cache in initState.
@override
void initState() {
super.initState();
context.read<DynamicShareModel>().clearState();
}
Copy the code
At the same time, in DynamicAddWrapper this package on the class, you need to use the ChangeNotifierProvider. In a way that is the value and edit pages share a singleton DynamicShareModel state management.
class DynamicAddWrapper extends StatelessWidget {
DynamicAddWrapper({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
returnChangeNotifierProvider.value( value: DynamicShareModel.sharedDynamicModel, child: _DynamicAdd(), ); }}Copy the code
The edit page is similar, except that you need to clear the state cache in initState before requesting dynamic details:
@override
void initState() {
super.initState();
context.read<DynamicShareModel>().clearState();
context.read<DynamicShareModel>().getDynamic(widget.dynamicId);
}
Copy the code
The edit page and add page forms are almost the same, except for the submit button name and the post-submission logic.
// Add the page
DynamicForm(
watchState.formData,
readState.handleTextFieldChanged,
readState.handleClear,
'submit',
() {
readState.handleAdd().then((success) {
if(success) { context.read<DynamicModel>().add(readState.currentDynamic); Navigator.of(context).pop(); }}); }, readState.handleImagePicked, imageFile: watchState.imageFile, ), );// Edit the page
DynamicForm(
watchState.formData,
readState.handleTextFieldChanged,
readState.handleClear,
'save',
() {
readState.handleEdit().then((success) {
context.read<DynamicModel>().update(watchState.currentDynamic);
Navigator.of(context).pop();
});
},
readState.handleImagePicked,
imageFile: watchState.imageFile,
imageUrl: watchState.currentDynamic.imageUrl,
);
Copy the code
This completes the implementation of two pages and shared state management.
The results
The result was exactly what we expected, and you can try to debug it without knowing what the cache will look like. It’s easy to accidentally forget to clear the cache during actual development, so sharing state may not be the best option from a code maintainability perspective, on a case-by-case basis.
conclusion
This paper introduces the use of the Provider ChangeNotifierProvider. The value of the ways to share state between unrelated pages data. Steps as follows:
- Create the same object that both pages can access, usually using singletons or containers.
- Create a package Widget to use
ChangeNotifierProvider.value
Wrap the page for access to the shared state object. - If the data shared between pages may have changed due to the actions of another page, you need to see if the state cache needs to be cleared (some may need to be synchronized rather than cleared).
- Page component reference states complete interface rendering and interaction.
This is just an example, and it feels a little awkward when you actually write it, but state sharing is more suitable for different operations on the same object, such as clicking Edit from the details page to the edit page. In this article, adding and editing state sharing improves code reusability, but reduces maintainability and breaks the single responsibility principle, so you can decide whether to share state or not based on the actual situation during development.
I’m an island user with the same name on wechat. This is a column on introduction and practice of Flutter.
ππ» : feel a harvest please point to encourage!
π : Collect articles, convenient to read back!
π¬ : Comment exchange, mutual progress!