Skip to content

Commit 22a4bfa

Browse files
authored
Merge pull request #10 from shubham-gupta-16/improve_view_model
Fixed ViewModel Dispose major bug
2 parents e6a0710 + d34ba63 commit 22a4bfa

File tree

10 files changed

+142
-4
lines changed

10 files changed

+142
-4
lines changed

.github/workflows/publish.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Publish to pub.dev
2+
3+
on:
4+
push:
5+
tags:
6+
- '[0-9]+.[0-9]+.[0-9]+*'
7+
8+
jobs:
9+
publish:
10+
uses: dart-lang/setup-dart/blob/main/.github/workflows/publish.yml
11+
# with:
12+
# working-directory: path/to/package/within/repository

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.5.3
2+
Fixed ViewModel Dispose major bug
3+
- ViewModel not disposing fixed
4+
- Responsive Example added
5+
16
## 0.5.2
27
Fixed Bugs and make package simpler
38
- ViewModelStatelessWidget removed

example/lib/more_examples_section.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import 'package:example/multiple_view_models_example/multiple_view_models_example.dart';
22
import 'package:example/post_frame_callback_example/post_frame_callback_example.dart';
3+
import 'package:example/responsive_example/responsive_example.dart';
34
import 'package:flutter/material.dart';
45

56
final _moreExamples = {
67
"Multiple ViewModels Example": const MultipleViewModelsExample(),
78
"PostFrameCallback Example": const PostFrameCallbackExample(),
9+
"Responsive Example": const ResponsiveExample(),
810
};
911

1012
class MoreExamplesSection extends StatelessWidget {

example/lib/multiple_view_models_example/view_model/second_view_model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ class SecondViewModel extends ViewModel {
2121
@override
2222
void dispose() {
2323
_messageSharedFlow.dispose();
24-
debugPrint("FirstViewModel disposed");
24+
debugPrint("SecondViewModel disposed");
2525
}
2626
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:view_model_x/view_model_x.dart';
3+
4+
import 'view_model/first_view_model.dart';
5+
import 'view_model/second_view_model.dart';
6+
7+
class ResponsiveExample extends StatelessWidget {
8+
const ResponsiveExample({super.key});
9+
10+
@override
11+
Widget build(BuildContext context) {
12+
final isDesktop = MediaQuery.of(context).size.width > 600;
13+
return Scaffold(
14+
appBar: AppBar(
15+
title: const Text("Responsive"),
16+
),
17+
body: isDesktop
18+
? const FirstSection()
19+
: ViewModelProvider(
20+
create: (context) => SecondViewModel(),
21+
child: const SecondSection()),
22+
);
23+
}
24+
}
25+
26+
class FirstSection extends StatelessWidget {
27+
const FirstSection({Key? key}) : super(key: key);
28+
29+
@override
30+
Widget build(BuildContext context) {
31+
return ViewModelProvider(
32+
create: (c) => FirstViewModel(),
33+
builder: (ctx, v) => Container(
34+
color: Colors.green,
35+
child: Center(
36+
child: Text(ViewModelProvider.of<FirstViewModel>(ctx)
37+
.counterStateFlow
38+
.value
39+
.toString()),
40+
),
41+
),
42+
);
43+
}
44+
}
45+
46+
class SecondSection extends StatelessWidget {
47+
const SecondSection({Key? key}) : super(key: key);
48+
49+
@override
50+
Widget build(BuildContext context) {
51+
return Container(
52+
color: Colors.yellow,
53+
);
54+
}
55+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:view_model_x/view_model_x.dart';
3+
4+
class FirstViewModel extends ViewModel {
5+
// initialize StateFlow
6+
final _counterStateFlow = MutableStateFlow<int>(1);
7+
8+
StateFlow<int> get counterStateFlow => _counterStateFlow;
9+
10+
void increment() {
11+
// by changing the value, listeners were notified
12+
_counterStateFlow.value = _counterStateFlow.value + 1;
13+
}
14+
15+
@override
16+
void dispose() {
17+
// must dispose all flows
18+
_counterStateFlow.dispose();
19+
debugPrint("FirstViewModel disposed");
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:view_model_x/view_model_x.dart';
3+
4+
class SecondViewModel extends ViewModel {
5+
// initialize SharedFlow
6+
final _messageSharedFlow = MutableSharedFlow<String>();
7+
8+
SharedFlow<String> get messageSharedFlow => _messageSharedFlow;
9+
10+
void showPopupMessage() {
11+
// by emitting the value, listeners were notified
12+
debugPrint("hi");
13+
_messageSharedFlow.emit("Hello from MyViewModel!");
14+
}
15+
16+
@override
17+
void init() {
18+
debugPrint("init inside vm");
19+
}
20+
21+
@override
22+
void dispose() {
23+
_messageSharedFlow.dispose();
24+
debugPrint("SecondViewModel disposed");
25+
}
26+
}

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ packages:
176176
path: ".."
177177
relative: true
178178
source: path
179-
version: "0.5.2"
179+
version: "0.5.3"
180180
sdks:
181181
dart: ">=2.18.6 <3.0.0"
182182
flutter: ">=1.17.0"

lib/src/view_model_provider.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
import 'package:flutter/widgets.dart';
22
import 'package:provider/provider.dart';
3+
import 'package:provider/single_child_widget.dart';
34

45
import 'provider_single_child_widget.dart';
56
import 'view_model.dart';
67

78
/// [ViewModelProvider] is used to wrap the widget with your custom [ViewModel].
89
/// This requires [create] which accepts custom [ViewModel] and [child] Widget.
10+
class VMP<T extends ViewModel> extends SingleChildStatelessWidget {
11+
const VMP({super.key, super.child});
12+
13+
@override
14+
Widget buildWithChild(BuildContext context, Widget? child) {
15+
// TODO: implement buildWithChild
16+
throw UnimplementedError();
17+
}
18+
}
19+
920
class ViewModelProvider<T extends ViewModel> extends Provider<T>
1021
with ProviderSingleChildWidget {
1122
ViewModelProvider(
1223
{super.key,
1324
required super.create,
1425
super.lazy,
1526
super.builder,
16-
super.child});
27+
super.child})
28+
: super(dispose: _dispose);
29+
30+
static void _dispose<T extends ViewModel>(BuildContext context, T viewModel) {
31+
debugPrint('provider dispose');
32+
viewModel.dispose();
33+
}
1734

1835
/// [ViewModelProvider].[of] method allows to get the custom [ViewModel] from anywhere nested inside [ViewModelProvider]'s [child]
1936
static F of<F extends ViewModel>(BuildContext context) {

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: view_model_x
22
description: An Android similar state management package (StateFlow and SharedFlow with ViewModel) which helps to implement MVVM pattern easily.
3-
version: 0.5.2
3+
version: 0.5.3
44
homepage: https://github.com/shubham-gupta-16/view_model_x
55
repository: https://github.com/shubham-gupta-16/view_model_x
66
issue_tracker: https://github.com/shubham-gupta-16/view_model_x/issues

0 commit comments

Comments
 (0)