Skip to content

Commit

Permalink
Merge pull request #1 from davidsdearaujo/main
Browse files Browse the repository at this point in the history
[BuilderPlus] Include "buildWhen"
  • Loading branch information
AlvaroVasconcelos authored Jul 29, 2024
2 parents 7cfad0e + d931570 commit 30abb55
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 21 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ class CounterPage extends StatelessWidget {
}
```

**Para controlar com precisão quando a função `builder` é chamada, pode-se fornecer opcionalmente um `buildWhen`. O `buildWhen` recebe o estado anterior e o estado atual do `ValueNotifierPlus` e retorna um booleano. Se `buildWhen` retornar verdadeiro, `builder` será chamado com o `state` e o widget será reconstruído. Se `buildWhen` retornar falso, `builder` não será chamado com o `state` e nenhuma reconstrução ocorrerá.**

```dart
BuilderPlus<CounterNotifier, int>(
notifier: counterNotifier,
buildWhen: (previousState, state) {
// retorna true/false para determinar quando
// reconstruir o widget com o novo estado.
return state > previousState + 2;
},
builder: (context, state) {
return Text('Counter: $state');
},
),
```


### `ListenerPlus`

O `ListenerPlus` é um widget que executa uma função sempre que o valor do `ValueNotifierPlus` muda, sem reconstruir a árvore de widgets. É similar ao `BlocListener` do pacote `flutter_bloc`.
Expand Down
15 changes: 11 additions & 4 deletions lib/src/widgets/builder_plus.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import 'package:flutter/widgets.dart';
import '../../value_notifier_plus.dart';

import '../../value_notifier_plus.dart';
import 'callbacks_plus.dart';

typedef BuilderPlusWhen<T> = bool Function(T previous, T current);

class BuilderPlus<N extends ValueNotifierPlus<S>, S> extends StatefulWidget {
const BuilderPlus({
Key? key,
required this.builder,
required this.notifier,
this.buildWhen,
}) : super(key: key);
final WidgetBuilderPlus<S> builder;
final N notifier;
final BuilderPlusWhen? buildWhen;

@override
State<BuilderPlus<N, S>> createState() => _BuilderPlusState<N, S>();
Expand Down Expand Up @@ -40,9 +44,12 @@ class _BuilderPlusState<N extends ValueNotifierPlus<S>, S>
}

void _listener() {
setState(() {
state = notifier.state;
});
final buildWhen = widget.buildWhen;
if (buildWhen == null || buildWhen(state, notifier.state)) {
setState(() {
state = notifier.state;
});
}
}

@override
Expand Down
75 changes: 58 additions & 17 deletions test/src/widgets/builder_plus_test.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,66 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:value_notifier_plus/value_notifier_plus.dart';

import '../../conter_notifier.dart';

void main() {
testWidgets('BuilderPlus rebuilds when state changes', (tester) async {
final counterNotifier = CounterNotifier();

await tester.pumpWidget(
BuilderPlus<CounterNotifier, int>(
notifier: counterNotifier,
builder: (context, state) {
return Text('$state', textDirection: TextDirection.ltr);
},
),
);

expect(find.text('0'), findsOneWidget);
counterNotifier.increment();
await tester.pump();
expect(find.text('1'), findsOneWidget);
group('BuilderPlus', () {
testWidgets('rebuilds when state changes', (tester) async {
final counterNotifier = CounterNotifier();

await tester.pumpWidget(
BuilderPlus<CounterNotifier, int>(
notifier: counterNotifier,
builder: (context, state) {
return Text('$state', textDirection: TextDirection.ltr);
},
),
);

expect(find.text('0'), findsOneWidget);
counterNotifier.increment();
await tester.pump();
expect(find.text('1'), findsOneWidget);
});

testWidgets('do NOT rebuilds when "buildWhen" is not true', (tester) async {
final counterNotifier = CounterNotifier();

await tester.pumpWidget(
BuilderPlus<CounterNotifier, int>(
notifier: counterNotifier,
buildWhen: (previous, current) => current > previous + 2,
builder: (context, state) {
return Text('$state', textDirection: TextDirection.ltr);
},
),
);

expect(find.text('0'), findsOneWidget);
counterNotifier.increment();
await tester.pump();
expect(find.text('0'), findsOneWidget);
});

testWidgets('rebuilds when "buildWhen" is true', (tester) async {
final counterNotifier = CounterNotifier();

await tester.pumpWidget(
BuilderPlus<CounterNotifier, int>(
notifier: counterNotifier,
builder: (context, state) {
return Text('$state', textDirection: TextDirection.ltr);
},
),
);

expect(find.text('0'), findsOneWidget);
counterNotifier.increment();
counterNotifier.increment();
counterNotifier.increment();
await tester.pump();
expect(find.text('3'), findsOneWidget);
});
});
}

0 comments on commit 30abb55

Please sign in to comment.